R [oman | everse] Notacja polska

11

Jest to rok MDLXVII w świecie, w którym Imperium Rzymskie nigdy nie upadło, a upadek w ciemne wieki nigdy nie miał miejsca. Ze względu na długi okres Pax Romana stabilność ekonomiczna imperium umożliwiła szybki rozwój technologii.

Rzymianie zaczęli bawić się obwodami i wymyślili genialny kalkulator, który nie wymaga użycia przycisku „równa się”. Nazywają to „notacją rzymsko-polską”

Aby wykonać obliczenia, najpierw wprowadzają operandy, a następnie operację.

Na przykład byłoby 100 + 11 * 20 C XI XX * +.

dodatkowo

Rzymianie odkryli, że często muszą wykonywać wiele obliczeń w tym samym czasie i wolą, aby metoda zwracała każdą wartość „na stosie” w jakiejś strukturze typu tablica / lista / krotka. (np. X I + X I - CC II +zwróci [11, 9, 202])


Wyzwaniem jest opracowanie programu kalkulatora zdolnego do wykonywania tych obliczeń.

Wyjaśnienie : Wymagana jest notacja odejmująca. Nie zdawałem sobie sprawy, że nie było to rozpoznawalne w starożytnym imperium rzymskim. Zadanie było zatem dwuznaczne i przepraszam.

Minimalne wytyczne

  • Twój wynik będzie w cyfrach arabskich.
  • Musisz tylko przekonwertować z cyfr rzymskich do 5000.
  • Będziesz musiał obsługiwać operacje +, -, /, * (dodawanie, odejmowanie, dzielenie i mnożenie).
  • To, czy podział jest oparty na liczbach zmiennoprzecinkowych, czy na liczbach całkowitych, zależy od implementacji. Albo działa na to wyzwanie.
  • Twój wynik będzie musiał obsługiwać liczby do 4 miliardów.
  • Najkrótsza odpowiedź ogółem, I wygrywa w każdym języku. To jest Code Golf Challenge, ale uwielbiam różnorodność.

W przypadku remisu, czynniki takie jak obsługa cyfr rzymskich powyżej 5000 lub dodatkowe operacje zostaną uznane za najwcześniejsze zgłoszenie wygra.

Jesse Daniel Mitchell
źródło
1
Czy możemy przyjmować dane wejściowe jako listę ciągów znaków, z których każdy ma albo liczbę rzymską, albo operator?
user202729,
czy dane wejściowe mogą być pisane małymi literami, czy też muszą być pisane wielkimi literami?
dzaima
1
@JesseDanielMitchell Uwaga: staraj się nie zmieniać zasad i unieważniać istniejące odpowiedzi . Ponadto (jak zwykle) sugeruję publikowanie w piaskownicy .
user202729

Odpowiedzi:

6

Python 2 + roman , 118 bajtów

from roman import*
s=[]
for i in input().split():s+=[eval(s.pop(-2)+i+s.pop())if i in"+-/*"else`fromRoman(i)`]
print s

Próbny

Nie można go przetestować online ze względu na moduł, z którego korzysta, ale możesz zobaczyć, jak go uruchomić tutaj (pełny program akceptujący dane wejściowe z STDIN - wyrażenie z cudzysłowami - i drukujący dane wyjściowe do STDOUT - w formie listy , stos). Używa nieco starszej wersji, ponieważ nie zawracam sobie głowy tworzeniem nowego GIF-a tylko dla kilku bajtów:

Demo GIF

Aby zainstalować pakiet, możesz uruchomić następujące polecenie w Terminalu / Wierszu poleceń:

pip install roman
Pan Xcoder
źródło
2
pyTester/Py.pyಠ_ಠ
totalnie ludzki,
@totallyhuman To tylko fikcyjny projekt, który stworzyłem właśnie dla tego ...
Pan Xcoder
6

Haskell , 217 bajtów

-13 bajtów dzięki Bruce Forte. -73 bajty dzięki Ørjan Johansen.

foldl(!)[].words
s@ ~(x:y:z)!n=last$(a n:s):[y`f`x:z|(f,c)<-zip[(+),(-),(*),(/)]"+-*/",n==[c]]
a s=last$0:[n+a(drop(length x)s)|(n,x)<-zip l$words"I IV V IX X XL L XC C CD D CM M",x<=s,x++"Y">s]
l=[1,4,5,9]++map(10*)l

Wypróbuj online!

Ręczna realizacja, tak!

całkowicie ludzki
źródło
2
Odciąłem to trochę (tak blisko pokonania nowego Pythona ...) Wypróbuj online!
Ørjan Johansen
1
Python też został odcięty. Ale jeśli jego argument, że notacja subtraktywna nie musi być poparta, zostanie podtrzymany, to i tu jest więcej oszczędności.
Ørjan Johansen
1
W każdym razie kolejne 3 bajty wyłączone l=1:4:5:9:map(10*)l.
ბიმო
Pamiętałem pozostałą sztuczkę, którą kiedyś znalazłem, do konwersji cyfr rzymskich, która automatycznie zajmuje się odejmowaniem. Wypróbuj online!
Ørjan Johansen
2

JavaScript (węzeł) + romans + stk-lang , 74 bajty

s=>(R=require)("stk-lang")(s.replace(/\w+/g,R("romans").deromanize)).stack

Zwraca listę bigintegerów.

Wykonanie

Uruchom następujące czynności:

npm install romans
npm install stk-lang
node

Następnie wklej funkcję. Przykład:

C:\Users\conorob\Programming\golf-new\roman
λ npm install romans
npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN Programming No description
npm WARN Programming No repository field.
npm WARN Programming No README data
npm WARN Programming No license field.

+ [email protected]
added 1 package in 0.801s

C:\Users\conorob\Programming\golf-new\roman
λ npm install stk-lang
npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\conorob\Programming\package.json'
npm WARN Programming No description
npm WARN Programming No repository field.
npm WARN Programming No README data
npm WARN Programming No license field.

+ [email protected]
added 1 package in 0.847s

C:\Users\conorob\Programming\golf-new\roman
λ node
> s=>(R=require)("stk-lang")(s.replace(/\w+/g,R("romans").deromanize)).stack
[Function]
> f=_
[Function]
> f("X I + X I - CC II +").map(e => e.toString())
[ '11', '9', '202' ]
> f("C XI XX * +").map(e => e.toString())
[ '320' ]
> f("MMMM M I - +").map(e => e.toString())
[ '4999' ]
Conor O'Brien
źródło
Ile osób używa lambda tak szybko?
Stan Strum
@StanStrum Podoba mi się i jest to ustawienie domyślne dla terminali takich jak cmder
Conor O'Brien
Nie wiedziałem tego. Chyba nigdy nie odstępowałem od $i >. Szczerze mówiąc, podoba mi się to
Stan Strum
2

Dyalog APL , 93 bajty

CY'dfns'
a←⍬⋄{0::{a,←⍵}roman⍵⋄f←⍎'+-÷×'⌷⍨'+-/*'⍳⍵⋄rf2aa↓⍨←¯2a,←r}¨{1↓¨⍵⊂⍨⍵∊' '}' ',⍞⋄a

Wypróbuj online!

116 bajtów bez wbudowanego rzymskiego

dzaima
źródło
Woah, nigdy wcześniej nie widziałem zmodyfikowanego przypisania do golfa
Zacharý
@ Zacharý to jedyny znany mi sposób modyfikowania zmiennej poza jej zasięgiem dfns, więc musiałem ją tutaj wykorzystać.
dzaima
Wybacz moją ignorancję, ale czym jest zmodyfikowane zadanie?
caird coinheringaahing
@cairdcoinheringaahing var fn←arr- odpowiada to var ← var fn arr. Tutaj jest używany w wielu miejscach, a,←⍵jako taki, który dołącza się do zmienneja
dzaima
1

Python 3 , 280 206 bajtów

N=dict(I=1,V=5,X=10,L=50,C=100,D=500,M=1000)
def d(s):
	n=0
	for v in map(N.get,s):n+=v-n%v*2
	return n
def c(w):
	s=[]
	for t in w.split():s+=[str(d(t)if t[0]in N else eval(s.pop(-2)+t+s.pop()))]
	return s

Wypróbuj online!

Tym razem z obsługą odejmowania notacji. metodac jest głównym punktem wejścia; drugi to wsparcie.

Edytuj dziennik:

David Foerster
źródło
Nie potrzebujesz bloków wcięć po ifi else.
Ørjan Johansen
Właściwie pozwólcie, że zaoferuję wam tę sztuczkę, którą kiedyś znalazłem:n+=v-n%v*2
Ørjan Johansen
1
Możesz także połączyć te dwa strzastosowania. Wypróbuj online!
Ørjan Johansen
0

JavaScipt (ES6), 152 151 bajtów

Zapisano 1 bajt dzięki user202729

p=>p.split` `.map(c=>s.push(eval("+-/*".indexOf(c)+1?(T=s.pop(),s.pop())+c+T:c.replace(/./g,c=>"+"+{I:1,V:5,X:10,L:50,C:100,D:500,M:1e3}[c]))),s=[])&&s

Przypadki testowe

Wyjaśnienie (mniej golfa)

V={I:1,V:5,X:10,L:50,C:100,D:500,M:1e3}     // Values of the roman numerals
p=>(
 s=[],                                      // Initialize the stack
 p.split` `.map(c=>                         // For every part in the input:
  "+-/*".indexOf(c)+1?                      //   If the input is an operator:
   s.push(eval((T=s.pop(),s.pop())+c+T))    //     Evaluate the operator on the top of the stack
  :                                         //   Else (if it is a roman numeral):
   s.push(eval(c.replace(/./g,c=>"+"+V[c])))//     Push the sum of the characters' values
 ),s)                                       // return the stack
Herman L.
źródło
Jestem pewien, że to 1e3również działa i oszczędza niektóre bajty.
user202729,
0

Galaretka , 82 bajty

ị“+-×÷”;”/v®ṫ-¤®ṖṖ¤;©
4Ḷ⁵*p1,5P€
“IVXLCDM”iЀị¢µIN‘Ṡæ.µ®;©
Ḳµ“+-*/”W€i⁸Ñ⁸Ǥ¹?µ€ṛ®Ḋ

Wypróbuj online!

Pierwotnie opublikowane na czacie .


Wyjaśnienie:

Ponieważ Jelly nie ma stosu, umieściłem go w rejestrze.

Po uruchomieniu programu wartością rejestru ®jest 0, co jest traktowane jak [0]na potrzeby tego programu.


ị“+-×÷”;”/v®ṫ-¤®ṖṖ¤;©       Link 1: Given an operator index (an
                            integer in range 1..4), apply it.

ị“+-×÷”                     Index to the string "+-×÷"
       ;”/                  Concatenate with the character "/",
                            which is Jelly splat operator.
          v   ¤             Evaluate with parameter...
           ®                  the register's
            ṫ                 tail
             -                from -1. (2 last items)
               ®  ¤;        Concatenate with the register value,
                ṖṖ            pop twice.
                    ©       Store the result to register.

4Ḷ⁵*p1,5P€          Link 2: Niladic, generate [1,5,10,50,...]
4Ḷ                  Lowered range of 4, gives [0,1,2,3].
  ⁵*                Raise to power of 10. Value = 1,10,100,1000.
    p1,5            Calculate Cartesian product with [1,5].
                      Value = [1,1],[1,5],[10,1],[10,5],...
        P€          Calculate product of each item.

Alternatively, ×þ1,5F would also work instead of p1,5P€.

“IVXLCDM”iЀị¢µIN‘Ṡæ.µ®;©   Link 3: Given roman number, push it
                            to the stack (register).
         i                  Find index of ...
          Ѐ                  each character ...
“IVXLCDM”                     in "IVXLCDM".
            ị¢              Index to last link. (link 2)
              µ             With that value, (consider LIX ->
                            [50,1,10] for example)
               I             
Ḳµ“+-*/”W€i⁸Ñ⁸Ǥ¹?µ€ṛ®Ḋ

[TODO complete explanation]

użytkownik202729
źródło
-1

Python 3 , 216 187 bajtów

from operator import*
N=dict(I=1,V=5,X=10,L=50,C=100,D=500,M=1000)
def f(w):
	s=[]
	for t in w.split():s+=[str(sum(map(N.get,t)))if t[0]in N else str(eval(s.pop(-2)+t+s.pop()))]
	return s

Wypróbuj online!

Ponieważ pojawił się w komentarzach zarówno do pytania, jak i do tej odpowiedzi i prawdopodobnie doprowadził do głosów negatywnych: to przesłanie nie obsługuje notacji odejmującej. Uzasadnienie: Notacja odejmująca była rzadko używana w Cesarstwie Rzymskim i spopularyzowana później (patrz Notacja odejmująca , akapit 3, ostatnie zdanie). Zadanie zakłada Cesarstwo Rzymskie, które opracowało programowalne układy scalone, a nie takie, które uległy takim samym zmianom kulturowym, jak Europa z XIII wieku. Opis nie wspomina o notacji odejmującej i żaden z przykładów go nie używa.

David Foerster
źródło
Hm ... nie obsługujecie liczb takich jak CIV(104).
Ørjan Johansen
... nie mogę zarzucić twojej logice. : P
Ørjan Johansen
2
Ach, miałeś rację. Nie myślałem o możliwej dwuznaczności, nie zdawałem sobie sprawy, że notacja subtraktywna nie była powszechną cechą starożytnego imperium rzymskiego.
Jesse Daniel Mitchell,
1
Właściwie zastanawiałem się nad pytaniem o notację odejmującą w ramach PO (i zauważyłem brak przykładu), ale byłem rozproszony. Jeśli myślisz o dwuznaczności definicji w przyszłych wyzwaniach, nie wahaj się, po prostu zapytaj (odpowiedź z zastrzeżeniem i link do komentarza powinien wystarczyć, jeśli chcesz opublikować). Teraz jest wyrok, powinieneś spróbować to naprawić :)
Jonathan Allan,