Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Hetket kahdella numerolla

PetriKeckman [03.07.2022 03:23:14]

#

Ohjelmointiprobleemia. Tämän vuoden 2022 helmikuu oli erikoinen siinä mielessä, että se sisälsi hetkiä minuutin tarkkuudella, mitkä olivat ilmaistavissa kahdella luvulla 0 ja 2. Ne olivat seuraavat 48 hetkeä:

Hetket 20 kirjoitti:

2/2/2022 0:00
2/2/2022 0:02
2/2/2022 0:20
2/2/2022 0:22
2/2/2022 2:00
2/2/2022 2:02
2/2/2022 2:20
2/2/2022 2:22
2/2/2022 20:00
2/2/2022 20:02
2/2/2022 20:20
2/2/2022 20:22
2/2/2022 22:00
2/2/2022 22:02
2/2/2022 22:20
2/2/2022 22:22
20/2/2022 0:00
20/2/2022 0:02
20/2/2022 0:20
20/2/2022 0:22
20/2/2022 2:00
20/2/2022 2:02
20/2/2022 2:20
20/2/2022 2:22
20/2/2022 20:00
20/2/2022 20:02
20/2/2022 20:20
20/2/2022 20:22
20/2/2022 22:00
20/2/2022 22:02
20/2/2022 22:20
20/2/2022 22:22
22/2/2022 0:00
22/2/2022 0:02
22/2/2022 0:20
22/2/2022 0:22
22/2/2022 2:00
22/2/2022 2:02
22/2/2022 2:20
22/2/2022 2:22
22/2/2022 20:00
22/2/2022 20:02
22/2/2022 20:20
22/2/2022 20:22
22/2/2022 22:00
22/2/2022 22:02
22/2/2022 22:20
22/2/2022 22:22
48
>

Ohjelmani, jolla listauksen tuotin oli hidas ja pitkä. Kuka keksisi paremman ja lyhyemmän?

rebol[]
substr: func [string start length][ ;tuottaa alimerkkijonon
  copy/part at string start length
]
print "odota"
day: 1/2/2022
laskeluvut: func[][ ;laskee kuinka monta eri lukua ajassa x/2/2022 x:xx on
	lukuja: copy[0 0 0 0 0 0 0 0 0 0]
	for i 0 9 1 [
		luku: to-string i
		for j 1 length? luvut 1 [
			if (luvut/(j) = to-string luku) [lukuja/(i + 1): lukuja/(i + 1) + 1]
		]
	]
	lkm: 0
	for k 1 length? lukuja 1 [
		if lukuja/(k) <> 0 [lkm: lkm + 1]
	]
	return lkm
]
lukumäärä: 0
while [day <= 28/2/2022][
	time: 0:00
	while [time <= 24:00][
		luvut: copy[]
		vuosi: to-string day/year
		for l 1 length? vuosi 1 [
			append luvut substr vuosi l 1
		]
		kuukausi: to-string day/month
		for l 1 length? kuukausi 1 [
			append luvut substr kuukausi l 1
		]
		päivä: to-string day/day
		for l 1 length? päivä 1 [
			append luvut substr päivä l 1
		]
		tunti: to-string time/hour
		for l 1 length? tunti 1 [
			append luvut substr tunti l 1
		]
		minuutit: to-string time/minute
		for l 1 length? minuutit 1 [
			append luvut substr minuutit l 1
		]
		if (laskeluvut <= 2) [ ;hyväksytäänkö tuotettu ajan hetki?
			lukumäärä: lukumäärä + 1
			stringinä: replace to-string day "feb" "2"
			stringinä: replace/all stringinä "-" "/"

			print [stringinä time]
		]
		time: time + 00:01 ;kasvatetaan aikaa minuutilla
	]
	day: day + 1 ;kasvatetaan päivää yhdellä
]
print lukumäärä
halt

Seuraavan kerran vastaavanlaista tapahtuu vasta vuonna 2111 tammi- ja helmikuussa. Entä mitkä vuoden 2111 jälkeen ovat vastaavanlaisia vuosia? Ainakin 2112. Listaus vuosistakin olisi kiva saada.

Ja unohdetaan vuodet, päivät ja kuukaudet. Mitä ajanhetkiä vuorokauden aikana löytyy, mitkä ovat ilmaistavissa kahdella (EDIT: tai yhdellä) luvulla? Kuten klo 00:00 ja klo 06:06

Metabolix [03.07.2022 14:27:27]

#

Tietysti yksinkertainen nopeutus ohjelmaan on se, että lasketaan erikseen päivämäärät ja kellonajat sitten yhdistetään nämä, ettei tarvitse kokeilla jokaiselle (myös vialliselle) päivälle jokaista (myös viallista) kellonaikaa. Lisäksi, kannattaako näitä edes yhdistää? Tuloksia on helpompi lukea (ja käyttää johonkin mielekkääseen tarkoitukseen kuten tapahtuman ajankohdan valintaan), jos voi ensin valita selvästä listasta päivämäärän ja sitten vasta miettiä hauskaa kellonaikaa.

Esimerkiksi tässä haetaan nuo helmikuun ”hauskat” päivät (3 kpl) ja kellonajat (16 kpl), ja sitten haetaan 1- tai 2-numeroiset päivämäärät vuosituhannen loppuun asti. Vaatinee 64-bittisen PHP-tulkin ja käyttöjärjestelmän, jottei aikaleima pyörähdä ympäri.

<?php
function time_range($start, $end, callable $next, ?callable $format = null, ?callable $filter = null) {
	for ($t = $start; $t <= $end; $t = $next($t)) {
		$s = $format ? $format($t) : $t;
		if (!$filter || $filter($s)) {
			yield $s;
		}
	}
}

// Helmikuu 2022, päivämäärät numeroista 0 ja 2.
print_r(iterator_to_array(time_range(
	start: strtotime("2022-02-01"),
	end: strtotime("2022-03-01"),
	next: fn($x) => strtotime("next day", $x),
	format: fn($x) => date("j.n.Y", $x),
	filter: fn($x) => strspn($x, "02.:") == strlen($x)
)));

// Kellonajat numeroista 0 ja 2.
print_r(iterator_to_array(time_range(
	start: strtotime("2000-01-01 00:00:00"),
	end: strtotime("2000-01-01 23:59:59"),
	next: fn($x) => $x + 60,
	format: fn($x) => date("G:i", $x),
	filter: fn($x) => strspn($x, "02.:") == strlen($x)
)));

// 2000–2999, vain 1 tai 2 numerosta muodostuvat päivämäärät.
print_r(iterator_to_array(time_range(
	start: strtotime("2000-01-01"),
	end: strtotime("2999-12-31"),
	next: fn($x) => strtotime("next day", $x),
	format: fn($x) => date("j.n.Y", $x),
	filter: fn($x) => strlen(count_chars($x, mode: 3)) <= 3 # eli 2 numeroa ja piste.
)));

Mielestäni tällaisten koodien tulosteita ei kannata tänne ahtaa. Jokainen ajakoon itse, jos kiinnostaa.

Vastaus

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

Tietoa sivustosta