Segmente der römischen Ziffernlinie

10

Schreiben Sie ein Programm oder eine Funktion, die eine Ganzzahl im Bereich 1..3999 als Eingabe akzeptiert und die Anzahl der Liniensegmente zurückgibt, die erforderlich sind, um diese Ganzzahl in römischen Standardzahlen auszudrücken (Sie würden also XL, aber keine VM verwenden). Beispiele:

   1 -> 1
   4 -> 3
   5 -> 2
   9 -> 3
  10 -> 2
  40 -> 4
  50 -> 2
  90 -> 3
 100 -> 1
 400 -> 3
 500 -> 2
 900 -> 5
1000 -> 4

Integrierte römische Zahlenkonvertierungen sind zulässig, aber Sie können das Problem ohne sie lösen, indem Sie wiederholt die größte verbleibende Zahl von der obigen Liste abziehen. Beispiel: 1234 = 4 + 1 + 1 + 2 + 2 + 2 + 3 = 15.

Dies ist , also gewinnt das kürzeste Programm.

Neil
quelle
Warum sind 10 zwei Liniensegmente statt vier? Wenn Sie X schreiben, schreiben Sie normalerweise nur zwei Zeilen, aber macht der Schnittpunkt der Zeilen nicht vier Segmente aus?
Alex A.
@AlexA. Die Definition des Liniensegments lautet normalerweise wie folgt: "Die Menge der Punkte, die dem kürzesten Weg zwischen zwei Punkten folgen". Es scheint keinen Grund zu geben, X basierend darauf zu schneiden. Sie benötigen nur zwei Sätze von Endpunkten, um es zu definieren. (Angenommen, die Römer haben hauptsächlich über euklidische Geometrien geschrieben, denke ich)
FryAmTheEggman
@FryAmTheEggman Hm okay. Gut zu wissen, danke.
Alex A.

Antworten:

2

Pyth, 92 76 70 Bytes

KsMc."/9hæ²z³Þ§ªW×Oû[Tnè,O¤"\/WQ=Q-Q=Nef!>TQ%2K aY@KhxKN;sY

Probieren Sie es hier aus!

Vielen Dank an @FryAmTheEggman für einige Vorschläge zum Packen von Strings, die mir einige Bytes erspart haben!

Ich frage mich immer noch, ob es eine mathematische Möglichkeit gibt, diese Liste zu codieren. Ich werde versuchen, etwas herauszufinden.

Erläuterung

Dies verwendet den angegebenen Algorithmus. Kenthält die angegebene Liste mit den Nummern und der entsprechenden Anzahl von Liniensegmenten im Wechsel. Diese Liste wird erstellt, indem eine gepackte Zeichenfolge aufgeteilt wird, die dekodiert wird 0/0/1/1/4/3/5/2/9/3/10/2/40/4/50/2/90/3/100/1/400/3/500/2/900/5/1000/4, /und jedes Element einer Ganzzahl zugeordnet wird.

KsMc. "..." \ / WQ = QQ = Nef!> TQ% 2K aY @ KhxKN; sY # Q = Eingabe

   c. "..." \ / # teile den String auf /
KsM # ordnet jede Zahl int zu und weist sie K zu
            WQ # während Q! = 0
                     f% 2K # nimm nur jedes 2. Element von K und filtere mit T.
                      !> TQ # T <= Q.
                  = Ne # Nimm das letzte Element davon und ordne es N zu
              = QQ # Q = Q - N.
                                   xKN # Index des ersten Auftretens von N in K.
                                  h # erhöht diesen Index, weil wir die Liniensegmente wollen
                              aA @ K # holt das Liniensegment aus diesem Index und hängt es an Y an
                                      ; sY # beende die Schleife und drucke die Summe aller Liniensegmente in Y.
Denker
quelle
3

C 148 129 Zeichen

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};f(c){while(d+=(c/n[x])*n[x+13],c%=n[x++]);return d;}

Mein erster Code-Golf: ^). Da die Frage besagt, dass ich eine Funktion verwenden kann, habe ich main in eine Funktion geändert, um einige Zeichen zu trimmen (am wichtigsten: Übergeben Sie c als Parameter, anstatt scanf).

unverpackt

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};
f(c){
  while(d+=(c/n[x])*n[x+13],
        c%=n[x++]);
  return d;
}
STDQ
quelle
2

Mathematica, 80 72 Bytes

Tr[Characters[#~IntegerString~"Roman"]/.{"I"|"C"->1,"M"->4,_String->2}]&

Anonyme Funktion, die nur Zahlen in römische Zahlen umwandelt, jedes Zeichen durch die Anzahl der Segmente ersetzt und die Summe berechnet.

LegionMammal978
quelle
2

Netzhaut, 128 Bytes

. +
$ *
1 {1000}
t '
1 {900}
td
1 {500}
d
1 {400}
t
1 {100}
'
1 {90}
t
1 {50}
d
1 {40}
t '
1 {10}
d
1 {9}
t
1 {5}
d
1 {4}
t
1
'
t
d '
d
''
'+
$ .0

Einfaches Ersetzen, bis nichts mehr zu ersetzen ist. Dann werden die Apostrophe gezählt und das ist unsere Anzahl von Liniensegmenten.

Wenn die Eingabe und Ausgabe in unary zulässig ist, sind es 115 Bytes (obwohl wer 1234 eingeben möchte?).

Probieren Sie es online aus!
Probieren Sie es online aus! (unäre IO)

daavko
quelle
2

Python 3, 95 Bytes

def f(a,b=0):
 for e in'᝴ᔝ஺ॣəȟĮô>9 ':e=ord(e);d=e//6;b+=a//d*(e%6);a%=d
 return b

Die Unicode-Zeichenfolge besteht aus den Codepunkten:

6004 5405 3002 2403 601 543 302 244 62 57 32 27 7
Lynn
quelle
Wenn Sie diese Zeichenfolge in ein Byte-Literal e=ord(e);
umwandeln,
Ich denke nicht, dass das in meinem Fall funktioniert. Ich brauche eine Unicode-Zeichenfolge :( dh ich durchlaufe die Codepunkte in dieser Zeichenfolge, nicht die Bytes.
Lynn
1
Oh, ich verstehe. Stört es Sie, einen Hex-Dump der Zeichenfolge bereitzustellen? Es wird auf meinem Telefon nicht richtig angezeigt.
Xsot
1

Java, 152 Bytes

Weil, weißt du, Java.

n->{int c=0;int[]r={999,4,899,5,499,2,399,3,99,1,89,3,49,2,39,4,9,2,8,3,4,2,3,3,0,1};for(int i=0;i<26;i+=2)while(n>r[i]){n-=r[i]+1;c+=r[i+1];}return c;}

Einfache wörtliche Implementierung des gegebenen Algorithmus. Das Array packt die Transformationsinformationen: Gerade Indizes sind eins weniger als die römische Zahl, und ungerade Indizes sind die Anzahl für diese Zahl.

Dies ist ein Lambda, das ein int/ nimmt und zurückgibt Integer. Dies beinhaltet IntUnaryOperatoroder UnaryOperator<Integer>.

CAD97
quelle
1

JavaScript (ES6), 79 Byte

n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4

Die Zeichenfolgen repräsentieren die Anzahl der Liniensegmente für die Einheiten, Zehner- und Hunderterstellen. (Tausend ist einfach viermal so groß wie die Tausenderstelle.) Diese Methode scheint kürzer zu sein als andere Optionen wie der in der Frage vorgeschlagene Algorithmus.

Bearbeiten: 2 Bytes dank @ user81655 gespeichert.

Neil
quelle
Dies ist ein cooler Algorithmus. Durch das Neuanordnen der Casts können auch 2 Bytes n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4
eingespart werden
@ user81655 Oh, das ist schön: Wenn ich einfach das +s in -s ändere, kann ich das führende entfernen +, aber dann speichert die Gruppierung ein weiteres Byte.
Neil