Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Ei taida päivän vinkki toimia?

PetriKeckman [29.10.2023 08:13:29]

#

Siis tämä: https://www.ohjelmointiputka.net/koodivinkit/23463-qb-viikonpäivän-selvitys

Testasin REBOL:lla. En saanut toimimaan sinne päinkään. Siis omaa REBOL-koodiani ilmeisesti?

rebol[]
Paivat: ["sunnuntai" "maanantai" "tiistai" "keskiviikko" "torstai" "perjantai" "lauantai" "sunnuntai"]
d1: 1/3/1800
d2: 31/12/2199
virheitä: 0
päiviä: 0
d: d1
print "Odota"
until [
	Paiva: d/day
	Kuukausi: d/month
	Vuosi: d/year
	if Kuukausi < 3 [
		Kuukausi: Kuukausi + 12
		Vuosi: Vuosi - 1
	]
	Vuosisata: Vuosi / 100
	Vuosi: mod Vuosi 100
	Kuukausi: to-integer((Kuukausi + 1) * 2.61)
	case [
		Vuosisata = 18 [Vuosisata: 2]
		Vuosisata = 19 [Vuosisata: 0]
		Vuosisata = 20 [Vuosisata: 6]
		Vuosisata =  21 [Vuosisata: 4]
	]
	Taikaluku: Vuosisata + Vuosi + Kuukausi + Paiva + to-integer(Vuosi / 4)
	Viikonpaiva: Paivat/((modulo Taikaluku 7) + 1)
	koodinpäivä: Viikonpaiva
	REBOLpäivä: Paivat/((d/weekday) + 1)
	if koodinpäivä <> REBOLpäivä [
		;print rejoin ["Virhe päivässä " d " ! " koodinpäivä "<>" REBOLpäivä]
		virheitä: virheitä + 1
	]
	d: d + 1
	päiviä: päiviä + 1
	d =  d2
]
print ["Päiviä välillä " d1 "-" d2 " on " päiviä ", joista virheellisiä " virheitä " eli " 100 * virheitä / päiviä " prosentti."]
halt

Tulosti:

Odota
Päiviä välillä  1-Mar-1800 - 31-Dec-2199  on  146037 , joista virheellisiä  108418  eli  74.240089840246  prosentti.
>>

Näillä arvoilla:

d1: 1/1/2000
d2: 29/10/2023

Toimi "sinne päin" ( - mikä kai ei ole sallittua? Sen pitäisi joko toimia tai sitten ei) vuodesta 2000 nykyhetkeen:

Odota
Päiviä välillä  1-Jan-2000 - 29-Oct-2023  on  8702 , joista virheellisiä  60  eli  0.689496667432774  prosentti.
>>

PS:

Taitaa olla QB koodissa jakomerkki väärinpäin:

Vuosisata = Vuosi \ 100

Ei siis tuo \ vaan / po.?

Grez [29.10.2023 09:51:47]

#

PetriKeckman kirjoitti:

Ei taida päivän vinkki toimia?

Siis tämä: https://www.ohjelmointiputka.net/koodivinkit/23463-qb-viikonpäivän-selvitys

Testasin REBOL:lla. En saanut toimimaan sinne päinkään. Siis omaa REBOL-koodiani ilmeisesti?

Niin jos mietit toimiiko vinkki vai ei niin kannattaa varmaan kokeilla alkuperäisellä kielellä.

PetriKeckman kirjoitti:

Taitaa olla QB koodissa jakomerkki väärinpäin:

Vuosisata = Vuosi \ 100

Ei siis tuo \ vaan / po.?

Niin QB:ssä \ on kokonaislukujako .. Eli 1960 / 100 = 19. Ja / on liukulukujako, eli 1960 / 100 = 19.6 tai jos sen sijoittaa kokonaislukumuuttujaan niin 20.

Eli vaikuttaisi siltä että suurin ongelma on että yrität kääntää ohjelmaa sellaisesta kielestä, jota et ymmärrä. Ja lähtökohtaisesti viikonpäivien laskeminen tuolla tyylillä on melko absurdia moderneissa kielissä, joissa on sisäänrakennettu kalenteritoiminnallisuus.

Toimisiko tämä paremmin:

REBOL []

kysy-pv: func [
    "Kysy käyttäjältä päivä"
] [
    print "Anna päivämäärä (YYYY-MM-DD):"
    date-str: ask ""
    date: to-date date-str
    return date
]

viikonpäivä: func [pv] [
    päivät: ["Sunnuntai" "Maanantai" "Tiistai" "Keskiviikko" "Torstai" "Perjantai" "Lauantai"]
    return päivät pick pv/weekday + 1
]

pv: kysy-pv
vkpv: viikonpäivä pv
print rejoin ["Viikonpäivä päivälle" pv "on" vkpv]

jalski [29.10.2023 10:50:49]

#

Kokeilin piruuttani 8th:lla ja näytti kyllä toimivan...

: wd \ s -- s
  [ "Sunnuntai", "Maanantai", "Tiistai", "Keskiviikko",
    "Torstai", "Perjantai", "Lauantai" ]

  swap "." s:/ ' >n a:map
  1 a:@ 3 n:< if
    1 ( 12 n:+ ) a:op!
    2 ' n:1- a:op!
  then

  1 ( n:1+ 2.61 n:* n:int ) a:op!
  -1 a:@ 100 n:/mod
  -rot 2 swap a:!

  swap >r
  [ ( r@ 18 n:= ) , ( 2 ) ,
    ( r@ 19 n:= ) , ( 0 ) ,
    ( r@ 20 n:= ) , ( 6 ) ,
    ( r@ 21 n:= ) , ( 4 ) ,
    ( r@ ) ] a:when rdrop

   a:push
   2 a:@ 4 n:/ n:int a:push
   ' n:+ 0 a:reduce
   7 n:mod a:_@ ;

: app:main
  "29.10.2023" wd . cr
  "01.02.2020" wd . cr ;

Ajettuna antaa:

C:\temp\game>8th wd.8th
Sunnuntai
Lauantai

PetriKeckman [29.10.2023 13:12:20]

#

Grez kirjoitti:

Niin jos mietit toimiiko vinkki vai ei niin kannattaa varmaan kokeilla alkuperäisellä kielellä.

No ei, kun QB:ssä ei ole sisäänrakennettua viikonpäivä funktiota, niin mihin tuon vinkin koodin tuloksia vertailisin? Tietysti olisin voinut tulosta QB:n tulokset tiedostoon ja ladata ne REBOL-ohjelmaan ja vertailla tuloksia REBOL ohjelma /weekday toimintoon, mutta paljon helpompaa oli yrittää vääntää kääntää koodin idea REBOL-kieliseksi.

Grez kirjoitti:

PetriKeckman kirjoitti:

Taitaa olla QB koodissa jakomerkki väärinpäin:

Vuosisata = Vuosi \ 100

Ei siis tuo \ vaan / po.?

Niin QB:ssä \ on kokonaislukujako .. Eli 1960 / 100 = 19. Ja / on liukulukujako, eli 1960 / 100 = 19.6 tai jos sen sijoittaa kokonaislukumuuttujaan niin 20.

Joo, kun muutin REBOL-ohjelmassa lausekkeen muotoon:

Vuosisata: to-integer (Vuosi / 100)

niin REBOL ohjelmakin toimi.

Grez kirjoitti:

Eli vaikuttaisi siltä että suurin ongelma on että yrität kääntää ohjelmaa sellaisesta kielestä, jota et ymmärrä.

No se oli tuon yhden merkin osalta ongelma.

Grez kirjoitti:

Ja lähtökohtaisesti viikonpäivien laskeminen tuolla tyylillä on melko absurdia moderneissa kielissä, joissa on sisäänrakennettu kalenteritoiminnallisuus.

Päin vastoin! Jos kerta halusin testata, että toimiiko vinkki, niin totta kai minun täytyi testata vastaavaa algoritmia kielellä, jossa on sisäänrakennettu viikonpäivä kalenteritoiminnallisuus.

Grez kirjoitti:

Toimisiko tämä paremmin:

REBOL []

kysy-pv: func [
    "Kysy käyttäjältä päivä"
] [
    print "Anna päivämäärä (YYYY-MM-DD):"
    date-str: ask ""
    date: to-date date-str
    return date
]

viikonpäivä: func [pv] [
    päivät: ["Sunnuntai" "Maanantai" "Tiistai" "Keskiviikko" "Torstai" "Perjantai" "Lauantai"]
    return päivät pick pv/weekday + 1
]

pv: kysy-pv
vkpv: viikonpäivä pv
print rejoin ["Viikonpäivä päivälle" pv "on" vkpv]

Miksi tuon ohjelman teit? Eihän tuolla voi mitenkään tarkistaa toimiiko vinkin idea.

Metabolix [29.10.2023 18:15:20]

#

Lähetin puheena olevan koodivinkin kommentiksi laskurista vielä lyhennetyn version, ja laitan sen nyt tähänkin. Uusi versio toimii entistä laajemmalla alueella vuosilukuja kalenterin käyttöönotosta (1582) aina QB:n 16-bittisten kokonaislukumuuttujien rajoille.

Kommentoin koodiin myös, mihin toiminta perustuu: Vuosilukua koskevilla osilla saadaan tietoon maaliskuun ensimmäinen päivä. Karkauspäivä on siitä lukien vuoden viimeinen päivä, joten se ei vaadi muuta lisäkäsittelyä. Kuukausissa päästään eteenpäin sopivalla kertoimella, joka tuottaa pyöristettynä tämän 30 ja 31 päivän vuorottelun. Päivän numero lisätään sellaisenaan.

' Funktio laskee viikonpäivän.
' 0 = sunnuntai, 1 = maanantai, ..., 6 = lauantai.
FUNCTION Viikonpaiva(BYVAL Vuosi AS INTEGER, BYVAL Kuukausi AS INTEGER, BYVAL Paiva AS INTEGER)
	IF Kuukausi < 3 THEN
		Kuukausi = Kuukausi + 12
		Vuosi = Vuosi - 1
	END IF
	' Päivä huomioidaan suoraan.
	' Kuukausi huomioidaan kertoimella, joka pyöristyy oikein vuoden aikana.
	' Vuosiluvun viimeiset numerot huomioidaan, vuodessa on 1 päivä yli viikon.
	' Vuoden jako neljällä tuottaa lisäpäivän tavallisille karkausvuosille.
	' Viimeinen osa käsittelee karkausvuoden poikkeukset 100 ja 400 vuoden välein.
	Viikonpaiva = (Paiva + FIX((Kuukausi + 1) * 2.61) + (Vuosi MOD 100) + ((Vuosi MOD 100) \ 4) + (2 * (3 - ((Vuosi \ 100) MOD 4)))) MOD 7
END FUNCTION
PRINT Viikonpaiva(2023, 10, 29) ' tulostaa 0 = sunnuntai

PetriKeckman kirjoitti:

No ei, kun QB:ssä ei ole sisäänrakennettua viikonpäivä funktiota, niin mihin tuon vinkin koodin tuloksia vertailisin?

Tähän on äärimmäisen yksinkertainen ratkaisu: laita koodi funktioon (teinkin nyt tämän muutoksen vanhaan koodivinkkiin), käy läpi silmukassa päivämääriä järjestyksessä ja tarkista, että viikonpäivä vastaavasti etenee järjestyksessä. Viimeistelyksi riittää yhden oikean viikonpäivän tarkastaminen. Lähetin koodivinkin kommentiksi QB-testikoodin, jossa tämä on toteutettu. Takautuvasti ajatellen 1.1.1582 olisi ollut perjantai, joten esimerkiksi siitä voi aloittaa.

Aloitetaan päivästä 1.1.1582.
Vuosi  1582  alkaa viikonpäivällä  5
Vuosi  1583  alkaa viikonpäivällä  6
Vuosi  1584  alkaa viikonpäivällä  0
Vuosi  1585  alkaa viikonpäivällä  2
Vuosi  1586  alkaa viikonpäivällä  3
...
Vuosi  29995  alkaa viikonpäivällä  0
Vuosi  29996  alkaa viikonpäivällä  1
Vuosi  29997  alkaa viikonpäivällä  3
Vuosi  29998  alkaa viikonpäivällä  4
Vuosi  29999  alkaa viikonpäivällä  5
Näissä vuosissa oikeita viikonpäiviä oli  10379461  ja virheitä  0 .

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta