Gammal goding, men alltid kul att se olika lösningar på. (Gjorde en själv som Pelle behövde för några månader sen, men det var ett snabbt hafsjobb, ligger nånstans på filarean om någon behöver inspiration) <b>funktionen skall naturligtvis kunna bytas till vilket språk som helst.</b> Okej, det var dumt formulerat... Menade bara att man utan problem ska kunna byta mellan, säg, engelska och svenska. Naturligtvis skulle man kunna tänka sig språk med en annan uppbyggnad, men de skiter vi i (åtminstone tills vidare) Här kommer mitt förslag i c#. Snyggt, nästan exakt som min metod: http://www.pellesoft.se/communicate/userprogram/program.aspx?tid=638 Min variant är otroligt dålig så jag vet inte om jag vill visa den. Rekursion är alltid kul, men den tanken slog mig inte i detta exempel. Kändes inte som en rekursiv uppgift speciellt eftersom den ursprunliga versionen av min kod bara behövde klara tal upp till tusen (en uppgift på www.mathschallenge.net). Men onekligen finns det ett rekursivt "tema" i uppgiften... Björn, du ska vara medveten om att om du publicerar din kod så löper du en viss risk att få konstruktiv kritik. :-) "Hoppas att fler som följer "Veckans nöt"-trådarna tar upp kampen i www.mathschallenge.net. Jag vet inte hur den interna PelleSoft-ställningen är nu men Per Persson leder antagligen på 26:e plats före mig som ligger på 31:e. Niklas, du verkar ha stannat på runt 160:e. har du gett upp :-)" "Björn, du ska vara medveten om att om du publicerar din kod så löper du en viss risk att få konstruktiv kritik. :-)" <b>>Niklas, du verkar ha stannat på runt 160:e. har du gett upp :-)</b> Well jag har ärligt talat stannat upp lite jag också. De sista månaderna har jag bara löst två uppgifter. De jag har kvar nu börjar bli riktigt kluriga och inte heller jag har tid att lägga alltför mycket tid på detta...har dessutom fortfarande kvar den retfulla uppgift 22, med namnsummorna, som egentligen är skitenkel. har inte heller gjort nåt åt det på länge, kollade lite in där för en stund sen och småtittade på nån uppgift.. 90 plats för närvarande (41%). Och nej.. 22:an var inte svår ;) "Och nej.. 22:an var inte svår ;)" här kommer min 5raders dubbelt rekursiva c# lösning :P Roger : Snyggt :-) ah , det blev nog bakvänt när jag optimerade bort alla ifsatser .. det ska dessutom vara en spejs i :Veckans nöt #4; tal till text
Helt enkelt: Gör en funktion som omvandlar tal till text (alltså skriven text)
typ
TalTillText(3)="tre"
TalTillText(-45378)="minus fyrtiofemtusen trehundrasjuttioåtta"
funktionen skall naturligtvis kunna bytas till vilket språk som helst.Sv: Veckans nöt #4; tal till text
det är väl typ där det skiter sig eftersom alla språk nödvändigtvis inte har samma följd på tal när dom skriver talet i text...
ta tex danska , det är ju inte normalt någonstanns..
//RogerSv: Veckans nöt #4; tal till text
Alltså: samma grej som innan, men alla strängar skall ligga på nåt smart sätt så att det är lätt att byta ut dem. Strunta i andra språkuppbyggnader.Sv: Veckans nöt #4; tal till text
[Edit : Gjorde funktionen lite lättare att bygga ut för att klara större (mindre) tal]
[Edit2 : Funktionen klarar nu alla tal från -long.MaxValue till long.MaxValue, dvs alla tal som datatypen long kan hantera i .Net]
<b>Resultatet från en testkörning med -long.MaxValue (-9223372036854775807):</b>
<info>
minus nine quintillion two hundred and twenty-three quadrillion three hundred and seventy-two trillion thirty-six billion eight hundred and fifty-four million seven hundred and seventy-five thousand eight hundred and seven
</info>
Källa för begreppen quintillion o s v : http://www.jimloy.com/math/billion.htm
Och så själva koden...
public string[] zeronineteen=new string[20]{"zero","one","two","three","four","five",
"six","seven","eight","nine","ten",
"eleven","twelve","thirteen","fourteen",
"fifteen","sixteen","seventeen","eighteen",
"nineteen"};
public string[] twentyhundred=new string[9]{"twenty","thirty","forty","fifty","sixty",
"seventy","eighty","ninety","hundred"};
public string[] thousands=new string[7]{"","thousand ","million ","billion ","trillion ","quadrillion ","quintillion "};
public const string minus="minus";
public string GetNumberString(long number)
{
string result="";
bool negative=(number<0);
if (negative) number=-number;
int count=0;
while (true)
{
result=GetNumberString1000(number%1000) + " " + thousands[count] + result;
count++;
number/=1000;
if (number==0)
break;
}
return negative?minus + " " + result.Trim():result.Trim();
}
private string GetNumberString1000(long number)
{
string result;
if (number>=1000) throw new ArgumentOutOfRangeException("number","Parameter number must be less than 1000!");
if (number<0) throw new ArgumentOutOfRangeException("number","Parameter number must be larger than or equal to 0!");
if (number<100)
return GetNumberString100(number);
long hundreds=number/100;
string rest=GetNumberString100(number%100);
result=zeronineteen[hundreds] + " " + twentyhundred[8]; // twentyhundred[8]="hundred"
if (rest!="")
result+=" and " + rest;
return result;
}
private string GetNumberString100(long number)
{
if (number>=100) throw new ArgumentOutOfRangeException("number","Parameter number must be less than 100!");
if (number<0) throw new ArgumentOutOfRangeException("number","Parameter number must be larger than or equal to 0!");
if (number<20)
return zeronineteen[number];
long ten=number/10;
long one=number%10;
if (one==0)
return twentyhundred[ten-2];
else
return twentyhundred[ten-2] + "-" + zeronineteen[one];
}
Sv: Veckans nöt #4; tal till text
Men du har lite stiligare upplägg, och att jag kör med rekursion.
Undrar om det finns någon annan variant, hade varit intressant att se den i så fall.Sv: Veckans nöt #4; tal till text
Den klarar bara tal upp till 999 men jag har ialla fall skrivit den helt själv vilket jag är lite stolt över faktiskt. ;)
Men som sagt, den är så otroligt dålig men kan visa den om ni verkligen VERKLIGEN vill se den. Sv: Veckans nöt #4; tal till text
Hoppas att fler som följer "Veckans nöt"-trådarna tar upp kampen i www.mathschallenge.net. Jag vet inte hur den interna PelleSoft-ställningen är nu men Per Persson leder antagligen på 26:e plats före mig som ligger på 31:e. Niklas, du verkar ha stannat på runt 160:e. har du gett upp :-)Sv: Veckans nöt #4; tal till text
Sv: Veckans nöt #4; tal till text
Jag ligger på plats 533. Har inte orkat göra så många. Mycket med skola och vissa problem privat också. :)
Ska nog börja lite med mathschallenge igen efter helgen nu.
Och jag hoppas det kommer fler "Veckans nöt"-trådar. För att jag tycker det verkligen är kul.Sv: Veckans nöt #4; tal till text
Hehe okej jag postar väl koden då. Men som sagt, den är dålig och det är jag väl medveten om.
Har inte orkat ge variablerna så bra namn.
<code>
string ToTen[11] = { "","ett","tv†","tre","fyra","fem","sex","sju","†tta","nio" };
string Ten[10] = { "","tio","tjugo","trettio","fyrtio","femtio","sextio","sjuttio","†ttio","nittio" };
string TenToNineteen[10] = { "tio", "elva", "tolv", "tretton", "fjorton", "femton","sexton", "sjutton", "arton","nitton" };
string Hundred[10] = { "","etthundra","tv†hundra","trehundra","fyrahundra","femhundra","sexhundra","sjuhundra","†ttahundra","niohundra" };
string NumToText(int Num)
{
string Tmp="";
string gg="";
string sTal;
string sign="";
char gah[10];
gg.insert(0,itoa(Num,gah,10));
int tiotal=0;
int ental=0;
int hundratal=0;
sTal = (gg.substr(gg.length()-1));
ental = atoi(sTal.c_str());
if(Num>=1 && Num<10 || Num<=-1 && Num>=-10 )
{
Tmp = ToTen[ental];
}
if(Num>=10 && Num<100 || Num<=-10 && Num>=-100)
{
sTal = (gg.substr(gg.length()-2,1));
tiotal = atoi(sTal.c_str());
if(tiotal==1 && Num>0)
{
Tmp = TenToNineteen[ental];
} else if (tiotal==1 && Num<0) {
Tmp = TenToNineteen[ental];
} else {
Tmp = Ten[tiotal]+ToTen[ental];
}
}
if(Num>=100 && Num<1000 || Num<=-100 && Num>=-1000)
{
sTal = (gg.substr(gg.length()-3,1));
hundratal = atoi(sTal.c_str());
sTal = (gg.substr(gg.length()-2,1));
tiotal = atoi(sTal.c_str());
if(tiotal==1 && Num>0)
{
Tmp = Hundred[hundratal]+TenToNineteen[ental];
} else if (tiotal==1 && Num<0) {
Tmp = Hundred[hundratal]+TenToNineteen[ental];
} else {
Tmp = Hundred[hundratal]+Ten[tiotal]+ToTen[ental];
}
}
if(Num==0)
Tmp = "noll";
if(Num<0)
{
sign = "minus ";
}
return sign + Tmp;
}
</code>
edit: Kortade ner koden lite.Sv: Veckans nöt #4; tal till text
Njae, men jag har inte så mycket tid. Det har vart kvantfysik och annat. Men jag tror inte att jag nånsin kommer bli speciellt seriös, har jag lust kanske jag smiter in och försöker lösa nån uppgift, men inte mer än så.Sv: Veckans nöt #4; tal till text
Sv: Veckans nöt #4; tal till text
Sv: Veckans nöt #4; tal till text
Det är så jäkla anoying. Det måste vara något löjligt specialtecken i filen, typ att amerikanarna infört en ny bokstav som jag inte känner till eller något annat fjantigt :-) Jag vet att jag läser in alla namnen, jag får rätt värde på namnet COLIN som är testvärde. Helt otroligt att jag inte fått rätt svar på den...har helt slut på idéer. Ber inte om hjälp dock, ville bara få ur mig lite frustration :-)Sv: Veckans nöt #4; tal till text
oke , det _går_ att formatera den lite snyggare ;P
private static string TalTillText(long tal)
{
if (tal<0) return "minus " + TalTillText(-tal);
if (tal < 20) return new string [] {"zero ","one ","two ","three ","four ","five ","six ","seven ","eight ","nine ","ten ",
"eleven ","twelve ","thirteen ","fourteen ","fifteen ","sixteen ","seventeen ","eighteen ","nineteen "} [tal];
else if (tal < 100) return new string[] {"","","twenty","thirty","fourty","fifty","sixty","seventy","eightty","ninety"} [tal / 10] + ((tal % 10 == 0)?TalTillText(tal % 10):"");
else if (tal < 1000) return TalTillText( tal / 100) + "hundred " + TalTillText(tal % 100);
else return TalTillText(tal / (long)Math.Pow (10,((long)Math.Log10 (tal) / 3)*3)) +
new string[] {"","thousand ","million ","billion ","trillion ","quadrillion ","quintillion "} [((long)Math.Log10 (tal) / 3)] +
TalTillText( tal % (long)Math.Pow (10,((long)Math.Log10 (tal) / 3)*3));
}
<info>
-12345678901 blir
minus twelve billion three hundred fourtyfive million six hundred seventyeight thousand nine hundred one
</info>
Sv: Veckans nöt #4; tal till text
Det var dock ett litet fel i koden på raden som hanterar tal < 100. Den ska vara :
<code>
else if (tal < 100) return new string[] {"","","twenty","thirty","fourty","fifty","sixty","seventy","eightty","ninety"} [tal / 10] + ((tal % 10 == 0)?"":TalTillText(tal % 10));
</code>Sv: Veckans nöt #4; tal till text
((tal % 10 == 0)?" "
så att det blir ett mellanrum efter orden om dom inte slutar på en annan siffra.
//Roger
[edit] här kommer den slutgiltiga 1 rads versionen
(ok , jag skulle inte använda kod som serut så här , det är bara på kul ;) )
private static string TalTillText(long tal)
{
return
tal<0?"minus " + TalTillText(-tal):
tal<20?new string [] {"zero ", "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine ",
"ten ", "eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen "} [tal]:
tal<100?new string[] {"", "", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eightty", "ninety"} [tal / 10] + ((tal % 10 == 0)?" ":TalTillText(tal % 10)):
tal<1000?TalTillText( tal / 100) + "hundred " + TalTillText(tal % 100):
TalTillText(tal / (long)Math.Pow (10,((long)Math.Log10 (tal) / 3)*3)) + new string[] {"", "thousand ", "million ", "billion ", "trillion ", "quadrillion ", "quintillion "} [((long)Math.Log10 (tal) / 3)] + TalTillText( tal % (long)Math.Pow (10,((long)Math.Log10 (tal) / 3)*3));
}