Kirjoittaja: GeoHound
Kirjoitettu: 09.04.2003 – 09.04.2003
Tagit: koodi näytille, vinkki
Tämä ulostaa kokonaisluvut roomalaisiksi numeroiksi. Toimii vain kokonaisluvuilla (ei negatiivisiä lukuja).
<?php # Tehnyt KeoKeo (aka. GeoHound), http://keokeo.daug.net function rome_num($luku) { settype($luku, "integer"); if($luku <= 0) { exit("luku ei saa olla negatiivinen luku!"); } $tuhannet = floor($luku / 1000); $tuhannet2 = floor($luku / 1000); for ($tuhannet < 0; $tuhannet--;) { echo "M"; } $sadat = floor($luku / 100); $sadat2 = floor($luku / 100); $sadat = $sadat - ($tuhannet2 * 10); if ($sadat >= 9) { echo "CM"; $sadat-=9; } if ($sadat >= 5) { echo "D"; $sadat-=5; } if ($sadat >= 4) { echo "CD"; $sadat-=4; } for ($sadat < 0; $sadat--;) { echo "C"; } $kymmenet = floor($luku / 10); $kymmenet2 = floor($luku / 10); $kymmenet = $kymmenet - ($sadat2 * 10); if ($kymmenet >= 9) { echo "XC"; $kymmenet-=9; } if ($kymmenet >= 5) { echo "L"; $kymmenet-=5; } if ($kymmenet >= 4) { echo "XL"; $kymmenet-=4; } for ($kymmenet < 0; $kymmenet--;) { echo "X"; } $ykköset = $luku - ($kymmenet2 * 10); if ($ykköset >= 9) { echo "IX"; $ykköset-=9; } if ($ykköset >= 5) { echo "V"; $ykköset-=5; } if ($ykköset >= 4) { echo "IV"; $ykköset-=4; } for ($ykköset < 0; $ykköset--;) { echo "I"; } } ?>
En kokeillut mutta vaikuttaa ideana oudolta (kuka tarvitsee). Eiköhän tästä silti opi jotain (ainakin aloittelijat, esim. minä...) ja tyhmät ideathan ovat yleensä juuri hauskimpia.
no ei tää mun mielestä tyhmä idea oo.. ei kyllä hyödyllinenkään, mutta kyllähän tästäkin jotain oppii
aíniin ja voi tesmiä osoitteessa http://www.waakku.net/rome.php
Onko 999 roomalaisilla varmasti CMXCIX ja 99 on sen mukaan XCIX? Järkevämpi se ainakin olisi, jos se olisi IM, mutta en ole täysin varma oikeellisuudesta
Entä esim. 39? Onko se XXXIX (ohjelman mukaan) vai XIL (näin luulisin sen olevan)
Ainakin oppaan mukaan sanotaan että "Roomalaiset numerot eivät nykyään esiinny yhteyksissä, joissa niillä pitäisi suorittaa laskutoimituksia.". Eli toisinsanoen tommosia laskuja ei kai tehdä enään. Tosin en ole itsekkään ihan varma. Jos joku kertoisi onko tuo oikein/väärin voisin korjata asian.
Niin oppaassa oli tämmösiä esimerkkejä vaan, ei "IM":ää "IV = 4, IX = 9, XL = 40, XC = 90, CD = 400 ja CM = 900".
Ei tos tapahu mitää!
sä et osaa
Ihan kiva :)
kääntyyks tää beisic kääntäjäl??!
Sami kirjoitti:
Onko 999 roomalaisilla varmasti CMXCIX ja 99 on sen mukaan XCIX? Järkevämpi se ainakin olisi, jos se olisi IM, mutta en ole täysin varma oikeellisuudesta
Entä esim. 39? Onko se XXXIX (ohjelman mukaan) vai XIL (näin luulisin sen olevan)
Ajatellaanpa:
1. CMXCIX: Parseroituna: CM = 1000(M)-100(C)=900 + XC = 100(C)-10(X)=90 + IX = 10(X)-1(I)=9 = 999 IM: Parseroituna: IM = **** (Virhe: sadat, kymmenet ja ykköset määrittelemättä) 2. XXXIX: Parseroituna: XXX = 10(X)+10(X)+10(X)=30 + IX = 10(X)-1(I)=9 = 39 XIL: Parseroituna: X = 10(X) + IL = 50(L)-1(I)=4 = 49
Selvenikö?
Jälleen kommentoin ikivanhaan "nosto" ketjuun...
Sami kirjoitti:
Onko 999 roomalaisilla varmasti CMXCIX ja 99 on sen mukaan XCIX? Järkevämpi se ainakin olisi, jos se olisi IM, mutta en ole täysin varma oikeellisuudesta
Entä esim. 39? Onko se XXXIX (ohjelman mukaan) vai XIL (näin luulisin sen olevan)
Tässä täytyy ottaa huomioon roomalaisten numeroiden "kielioppisääntöjä"...
I toimii vähentimenä ainoastaan kirjaimille V ja X.
X toimii vähentimenä ainoastaan kirjaimille L ja C.
C toimii vähentimenä ainoastaan kirjaimille D ja M.
Mitä itse ohjelmaan tulee niin itse koodaisin sen mieluummin jotenkin näin:
<?php function rome_num($luku) { $luku = (int)$luku; $merkit = "MDCLXVI"; $tulos = str_repeat($merkit[0], $luku / 1000); for ($i = 0, $d = 100; $i<6; $i += 2, $d/=10) { $p = ($luku / $d) % 10; if ($p%5==4) { $tulos .= $merkit[$i + 2]; $p++; } if ($p == 10) { $tulos .= $merkit[$i]; continue; } if ($p >= 5) { $tulos .= $merkit[$i + 1]; $p -= 5; } $tulos .= str_repeat($merkit[$i + 2], $p); } return $tulos; }
Tämän tavan hyöty tietysti olisi suurempi, jos merkit jatkuisivat isompaan kuin tuhanteen.
Onkohan tuo koodi copy-pastettu monesta eri lähteestä, kun koodaustyyli vaihtelee riveittäin ja jopa for-operaattorin argumenttien sisällä...
Ilmeisesti viittaat tuohon minun koodiini kun siellä on eroa välilyönneissä..
Koodailen yleensä muulla kielellä kehitysympäristössä, joka automaattisesti yhtenäistää sisennykset ja välilyönnit yms. Koska yleensä en koodaile PHP:llä niin rustasin tuon perus tekstieditorilla. Siinä ei tosiaan ole mitään muuta copy&pastettua kuin tuo alkuperäisen koodivinkin funktiomäärittely, että se olisi "drop in replacement". Näköjään tosin erehdyin siinä koska tuo alkuperäinenhän tuuppaa tavaran pihalle echona funktion sisältä :(
Sen verran googletin että millä funktiolla PHP:ssä saa toistettua samaa merkkiä.
Yleensäkään en copy-pasteile koodiin rivin tai parin pätkiä, koska on nopeampaa vaan kirjoittaa ne. Oikeastaan koko esimerkkini pointti on, että miten tehdä nuo toistuvat asiat ohjelmallisesti eikä kopioimalla samaa koodia pienin muokkauksin kolmeen kertaan samaan funktioon.
Tokihan tuon voisi ajaa jonkun PHP-tyylittelijän läpi, ihmisen hommana en sellaista pidä.
Alun perin itse asiassa postasin tänne koodin suoraan tekstieditorista ilman testaamista. Sitten päätin kuitenkin testata että se ylipäätään toimii ja olihan siinä virhe. Alkuperäisessä koodissa oli for -loopissa $i<6; asemesta $d; Ajattelin että $d olisi kokonaislukumuuttuja ja lopuksi menisi 0:ksi, jonka PHP tulkitsisi epätodeksi, mutta eihän nuo PHP:n muuttujat ole tyypitettyjä, joten se ilmeisesti meni 0.1:ksi jne ja looppi ei katkennutkaan.
Tässä vielä tyyliteltynä: (koneella meni 139ms)
<?php function rome_num($luku) { $luku = (int) $luku; $merkit = "MDCLXVI"; $tulos = str_repeat($merkit[0], $luku / 1000); for ($i = 0, $d = 100; $i < 6; $i += 2, $d /= 10) { $p = ($luku / $d) % 10; if ($p % 5 == 4) { $tulos .= $merkit[$i + 2]; $p++; } if ($p == 10) { $tulos .= $merkit[$i]; continue; } if ($p >= 5) { $tulos .= $merkit[$i + 1]; $p -= 5; } $tulos .= str_repeat($merkit[$i + 2], $p); } return $tulos; }