Spójrz mamo! Zrobiłem swój własny system liczbowy (Base 10)! [Zamknięte]

21

Wszyscy to zrobiliśmy, no cóż, może nie, ale tworzenie własnego obcego języka i systemu numeracji jest podstawowym elementem pisania fantasy, ale przede wszystkim jest zabawą.

Zadanie jest proste, weź dwa dane wejściowe:

  1. Uporządkowana lista zawiera 10 [dziesięć] unikatowych „cyfr” (dowolnych drukowalnych znaków ASCII) i interpretuje je w kolejności jako wartości 0, 1, 2, 3, ..., 9

    + Istnieją wyjątki od tego, co może być cyfrą tutaj. Operatory arytmetyczne (+, -, *, /), nawiasy i spacje nie mogą być używane jako jedna z cyfr.

  2. Problem arytmetyczny z wykorzystaniem tylko tych „cyfr”

I wyprowadza równoważną liczbę całkowitą w podanej formie.

Oto przykład:

INPUT

abcdefghij

bcd + efg + hij
OUTPUT

bdgi

W tym przykładzie lista wejściowa (możesz wybrać, w jakiej formie się pojawi) „abcdefghij” odpowiada „0123456789”, podobnie jak „hjkloiwdfp” również odpowiada 1 do 1 z „0123456789”, gdzie zamiast „a” kojarzy się z zero, „h” robi. Arytmetyka po „tłumaczy” przekłada się na 123 + 456 + 789, co równa się 1368. Musi to zostać wyprowadzone w postaci, w jakiej ją otrzymaliśmy, więc b (co oznacza 1) d (dla 2) g (dla 6) i i (dla 8).

PRZYPADKI TESTOWE

abcdefghij
abc + def - ghij

-gedc
qwertyuiop
qwerty / uiop

e
%y83l;[=9|
(83l * 9) + 8%

y9|8

WIĘCEJ ZASAD

  • Standardowe luki są zabronione!
  • To jest kod golfowy, więc wygrywa najkrótsza odpowiedź w bajtach.
  • Musi to być pełny program lub funkcja przyjmująca wejścia i wyjścia w dowolnym formacie, który najbardziej Ci odpowiada. (Po prostu nie można dodać dodatkowych informacji do danych wejściowych, tylko „cyfry” i wyrażenie.
  • Używaj dowolnego języka (o ile jest zgodny z innymi zasadami)
Bill W.
źródło
9
Drugi przypadek testowy sugeruje, że końcowy wynik jest zaokrąglony, w przeciwnym razie wynik byłby q.ioiopewioyetqorw.... Jeśli tak, jakie zaokrąglenie należy zastosować?
Arnauld
2
Aby dodać do punktu @ SriotchilismO'Zaic, mamy również piaskownicę dla twojej korzyści i naszej; chodzi o to, aby umożliwić społeczności dopracowanie wyzwań, zanim zostaną opublikowane. Niezły pomysł na wyzwanie!
Giuseppe
3
Różne języki prawdopodobnie ocenią to samo równanie w różny sposób, nie jestem pewien, czy można to obejść. Na przykład, powraca T SQL 1dla 5/3, a nie 2, ze względu na podział całkowitej (brak zaokrąglenia). Nie unieważnia to wyzwania, ale może być konieczne dopuszczenie różnych akceptowalnych odpowiedzi dla tego samego przypadku testowego (zobacz moją odpowiedź T-SQL poniżej).
BradC,
2
@Giuseppe Wow, przeglądałem ten stos od dłuższego czasu i nigdy o tym nie wiedziałem! Byłby zdecydowanie pomocny, szczególnie jako pierwszy plakat (słuchacz od dawna), którym jestem. Będzie pamiętać na następny raz! Dziękuję za komentarz i odpowiedź.
Bill W
2
Interesującą odmianą tego byłoby ustawienie, które obsługuje dowolną bazę liczbową, w zależności od długości pierwszego ciągu wejściowego ...
Darrel Hoffman

Odpowiedzi:

11

05AB1E , 10 9 bajtów

žh‡.Eò¹Åв

(Teraz) wyprowadza jako listę znaków.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

          # Transliterate the second (implicit) input, replacing every character of 
           # the first (implicit) input with:
žh         # The builtin "0123456789"
   .E      # Then evaluate it as Elixir code
     ò     # Round it to the nearest integer
      ¹Åв  # And change it back by using a custom base-conversion with the first input as
           # base (which results in a character list)
           # (after which that result is output implicitly)

Nowa wersja 05AB1E to build, build w Elixir . .EFunkcja zadzwoni call_unary(fn x -> {result, _} = Code.eval_string(to_string(x)); result end, a), gdzie Code.eval_stringjest wbudowane Elixir .

Zauważ, że starsza wersja 05AB1E nie działa w tym celu, ponieważ jest wbudowana w Pythona. Liczby z wiodącymi zerami nie będą oceniane:
Zobacz wszystkie przypadki testowe w starszej wersji (która używa wersji 10-bajtowej, ponieważ Åвwbudowane jest nowe).

Kevin Cruijssen
źródło
8

R , 58 bajtów

function(d,s,`[`=chartr)'0-9'[d,eval(parse(t=d['0-9',s]))]

Wypróbuj online!

Używa translacji znaków, chartraby zamienić cyfry, parses i evals wyrażenia, a następnie chartrs z powrotem do oryginalnych cyfr.

Jeśli wymagane jest zaokrąglenie do najbliższej liczby całkowitej, jest to

R , 65 bajtów

function(d,s,`[`=chartr)'0-9'[d,round(eval(parse(t=d['0-9',s])))]

Wypróbuj online!

Giuseppe
źródło
Używanie [jako krótszej nazwy funkcji z 3 parametrami jest bardzo sprytne. Dobra robota.
Robin Ryder,
6

T-SQL, 117 bajtów

DECLARE @ CHAR(99)
SELECT @='SELECT TRANSLATE('+TRANSLATE(e,c,'0123456789')+',''0123456789'','''+c+''')'FROM t
EXEC(@)

Podziały linii służą wyłącznie do odczytu.

Wprowadzanie odbywa się za pomocą istniejącej tabeli t z kolumnami tekstowymi c (znaki) i e (równanie), zgodnie z naszymi zasadami IO .

Używa funkcji SQL 2017 TRANSLATEdo przełączania się między znakami i generowania ciągu zawierającego nie tylko równanie, ale także kod do przetłumaczenia z powrotem na oryginalne znaki:

SELECT TRANSLATE(123 + 456 + 789,'0123456789','abcdefghij') 

Ten ciąg jest następnie oceniany przy użyciu EXEC().

Może być kilka znaków (na przykład pojedynczy cytat ' ), które mogłyby złamać ten kod; Nie przetestowałem wszystkich możliwych znaków ASCII.

Pod kątem wyzwania oceniam podane wyrażenie, z zastrzeżeniem sposobu, w jaki mój język interpretuje te operatory. Jako taki, drugi przypadek testowy zwraca 1 ( w), a nie 2 ( e), z powodu podziału na liczby całkowite.

BradC
źródło
4

Perl 6 , 38 bajtów

{*.trans($_=>^10).EVAL.trans(^10=>$_)}

Wypróbuj online!

Nie jestem pewien, jak powinno działać zaokrąglanie. Jeśli zaokrągli się na końcu, mogę dodać .rounddla +6 bajtów . Jeśli zachowanie/ powinno być inne, może być dłuższe. Sprawia, że ​​wejście jest curry jak f(arithmetic)(numerals)(arithmetic).

Wyjaśnienie:

{                                    }  # Anonymous codeblock
 *                                      # Returning a whatever lambda
  .trans($_=>^10)       # That translates the numerals to digits
                 .EVAL  # Evaluates the result as code
                      .trans(^10=>$_)   # And translates it back again
Jo King
źródło
3

Stax , 74 66 65 bajtów

┼ö8Q#xóπcM~oÖ÷╦├mî☼yº─▐4ç≥e╘o▄ê‼ø_k╜ø8%N╫ ╗e<.╗P[─╛èA±!xêj«w╠°{B♪

Uruchom i debuguj

Stax nie radzi sobie tutaj dobrze, brakuje mu prawdziwej instrukcji „ewaluacji”. Ma taki, który w dokumentach nazywa się „eval”, ale działa tylko na wartościach dosłownych, a nie na pełnych wyrażeniach.

rekurencyjny
źródło
Może to nie być zgodne z częstością występowania operatora. Nie jesteś pewien, czy jest to wymagane? staxlang.xyz/…
dana
@dana: Dobra uwaga. Nie brałem tego pod uwagę. Poprawka prawdopodobnie będzie kosztować trochę bajtów, więc poczekam na wyjaśnienia, zanim spróbuję zmienić to zachowanie.
rekurencyjny
3

Bash, 97 bajtów

IFS=''
read S
read O
A=`echo "$O"|tr "$S" 0-9`
printf %0.f `bc<<<"(${A[@]##0})+0.5"`|tr 0-9 "$S"

Mogłoby być mniej, gdybyśmy mogli obciąć, a nie zaokrąglić. Trudne jest także posługiwanie się zerami wiodącymi (jak w przypadku testowym nr 2), ponieważ Bash interpretuje liczby zaczynające się od 0 jako ósemkowe.

spuck
źródło
Jaki jest konsensus w używaniu narzędzi takich jak „bc” i „tr” do gry w golfa?
spuck
1
Nie jestem ekspertem, ale myślę, że tego typu odpowiedzi są zazwyczaj przedstawiane jako „bash + coreutils”
Giuseppe
@Giuseppe trjest częścią coreutils, a bcnie jest. Niemniej jednak bcjest bardzo powszechnym narzędziem. Każde inne polecenie w tej odpowiedzi to bash.
rexkogitans
-7 bajtów skradzionych z odpowiedzi @ CM, zmniejszając „0123456789” do „0-9”
spuck
Definiowanie T nie jest już korzystne: $Tjest tylko jeden bajt krótszy niż 0-9, używasz go tylko dwa razy i wydajesz 8 bajtów, aby go zdefiniować.
ruds
2

Bean , 94 90 bajtów

Hexdump

00000000: 53d0 80d6 d800 d3d0 80a0 1f20 8047 53a0  SÐ.ÖØ.ÓÐ. . .GS 
00000010: 1753 d080 d3d0 80a0 5e20 800a a181 8100  .SÐ.ÓÐ. ^ ..¡...
00000020: 40a0 5f52 cac3 4da0 6580 53d0 80a0 5d20  @ _RÊÃM e.SÐ. ] 
00000030: 8089 205f a065 205f 2080 0aa1 8181 0123  .. _ e _ ..¡...#
00000040: 0058 0020 800a a181 8102 40a0 6550 84a0  .X. ..¡...@ eP. 
00000050: 5d20 652e dce2 b02b dc64                 ] e.Üâ°+Üd

JavaScript

`${Math.round(
  eval(
    b.replace(
      /./g,
      c => ~(i = a.indexOf(c)) ? i : c
    ).replace(
      /\b0+/g,
      ''
    )
  )
)}`.replace(
  /\d/g,
  i => a[i]
)

Wyjaśnienie

Ten program domyślnie przypisuje pierwszy i drugi wiersz danych wejściowych jako ciągi do zmiennych aib odpowiednio.

Każdy znak cw wierszu bjest zastępowany odpowiednim indeksem iznaku znalezionego w wierszua lub samego , jeśli nie został znaleziony.

Następnie usuwa każdą sekwencję jednego lub więcej 0s poprzedzoną granicą z wynikowego łańcucha. Zapobiega to eval()ocenieniu jakiejkolwiek sekwencji cyfr rozpoczynającej się 0od literału ósemkowego.

Po eval()i Math.round()wynik jest ponownie wymuszany na ciąg znaków, a każdy znak cyfry ijest zastępowany odpowiednim znakiem z wiersza ao indeksiei .

Przypadki testowe

Próbny

abcdefghij
abcd + efg + hij

bdgi

Próbny

abcdefghij
abc + def - ghij

-gedc

Próbny

qwertyuiop
qwerty / uiop

e

Próbny

%y83l;[=9|
(83l * 9) + 8%

y9|8
Patrick Roberts
źródło
2

Perl 5 -p , 63 bajtów

$p=<>;eval"y/$p/0-9/";s/\b0+\B//g;$_=int.5+eval;eval"y/0-9/$p/"

Wypróbuj online!

Pobiera wyrażenie w pierwszym wierszu wprowadzania, a listę tłumaczeń w drugim.

Xcali
źródło
1

Perl 5 , 130 bajtów

sub f{eval sprintf"'%.0f'=~y/%s/%s/r",eval(eval(sprintf"\$_[1]=~y/%s/%s/r",@r=map"\Q$_",$_[0],'0123456789')=~s,\b0,,gr),reverse@r}

Wypróbuj online!

Może ta podwójna ewaluacja może się jakoś zmienić s/.../.../geer.

Kjetil S.
źródło
1

Węgiel drzewny , 14 bajtów

⍘UV⭆η⎇№θι⌕θιιθ

Wypróbuj online! Link jest do pełnej wersji kodu. Uwaga: Wyrażenie jest oceniane zgodnie z semantyką języka Python 3, więc na przykład początkowe zera na liczbach niezerowych są nielegalne. Wyjaśnienie:

   ⭆η           Map over expression's characters and join
        ι       Current character
      №θ        Count matches in first input
     ⎇          If non-zero
         ⌕θι    Replace with position in first input
            ι   Otherwise keep character unchanged
 UV             Evaluate as Python 3
⍘            θ  Convert to base using first input as digits
Neil
źródło
Niestety wiodące 0s nie działają w Pythonie, który jest obecny w przypadkach testowych.
Jonathan Allan
0

Python 3 , 137 bajtów

Podejście inne niż wyrażenia regularne, w którym stosuje się str.translatei str.maketransdo zamiany znaków. Straciłem wiele znaków po przycięciu wiodących zer ...

lambda s,t,d='0123456789',e=str.translate,m=str.maketrans:e(str(round(eval(' '.join(c.lstrip('0')for c in e(t,m(s,d)).split())))),m(d,s))

Wypróbuj online!

Gábor Fekete
źródło
0

Python 3 , 167 bajtów

import re
a=[*enumerate(input())]
e=input()
for i,c in a:e=re.sub(c,str(i),e)
e=str(round(eval(re.sub(r'\b0+(?!\b)','',e))))
for i,c in a:e=re.sub(str(i),c,e)
print(e)

Wypróbuj online!

Miejsce na udoskonalenie...

movatica
źródło
Nadal kończy się niepowodzeniem w ostatnim przypadku testowym: tio.run/…
ruohola
0

Wolfram Language (Mathematica) , 121 bajtów

Definiuję funkcję czystą z dwoma argumentami. Ponieważ niektóre funkcje są powtarzane, zapisuję je w zmiennej, aby zapisać kilka znaków. Ten kod po prostu zastępuje ciągi znaków, a następnie używa ToExpressiondo oceny wyrażenia za pomocą jądra Wolfram.

(r=Thread[StringPartition[#,1]->(t=ToString)/@Range[0,9]];u[(u=StringReplace)[#2,r]//ToExpression//Round//t,Reverse/@r])&

Wypróbuj online!

MannyC
źródło
0

Lua , 162 151 150 bajtów

  • -11 bajtów dzięki mojemu pomysłowi użycia loadzamiastfunction(...) end
  • -1 bajt, pomijając znak nowej linii
l,p=...print(((math.ceil(load('return '..p:gsub('.',load'n=l:find(...,1,1)return n and n-1'))()-0.5)..''):gsub('%d',load'c=...+1 return l:sub(c,c)')))

Wypróbuj online!

Nie jest to najkrótsza rzecz na świecie (Lua zmusza cię do fantazji, szczególnie przez ogromne słowa kluczowe), ale tworzenie jej było całkiem fajne. Pełny program przyjmujący dane wejściowe jako argumenty i wynik drukowania.

Wyjaśnienie

Wprowadzenie

l,p=...

Przypisz wartości z argumentów do zmiennych. Nasz słownik jest li wyrażenie jest p.

Następujące wyrażenie jest dość trudne do zrozumienia, ponieważ ma dziwną kolejność wykonywania, więc wyjaśnię to krok po kroku:

Konwersja na liczby normalne

p:gsub('.',
load'n=l:find(...,1,1)return n and n-1')

Wykonaj zamianę na ciąg wyrażenia: weź każdy symbol i przekaż go do funkcji ( loadokazało się, że jest krótszy niż normalna deklaracja tutaj).

Funkcja wyszukuje pozycję wystąpienia w łańcuchu dict dla przekazanego symbolu za pomocą find. ...jest pierwszym (i jedynym) argumentem tutaj, ponieważ jesteśmy w funkcji vaarg (dowolna loadedycja), która jest naszym bieżącym symbolem. Następujące argumenty są wymagane, aby findzignorować specjalne symbole ( 1jest to tylko krótka wartość, która ocenia się tak, jak w trueprzypadku konwersji na wartość logiczną): pozycja początkowa (jeden jest tutaj wartością domyślną) i plainktóra faktycznie wyłącza obsługę wzorca. Bez tych programów nie powiedzie się trzeci przypadek testowy, ponieważ %jest wyjątkowy.

Jeśli znaleziono dopasowanie, odejmij jeden, ponieważ łańcuchy Lua (i tablice btw) są oparte na 1. Jeśli nie zostanie znalezione dopasowanie, nic nie zwróci, w wyniku czego nie zostanie wykonana zamiana.

Rozwiązywanie

math.ceil(load('return '..ABOVE)()-0.5)

Przygotuj się returnna nasze wyrażenie, aby zwrócił wynik, oblicz go, kompilując jako funkcję Lua i wywołując ją, wykonując zaokrąglanie ( to zamienił odwrót, aby krótszy).

Na końcu otrzymujemy numeryczne rozwiązanie naszego problemu, pozostaje tylko jego konwersja.

Znowu to wariuje

(ABOVE..'')
:gsub('%d',load'c=...+1 return l:sub(c,c)')

Pierwszy wiersz to krótki sposób na konwersję liczby na ciąg, dzięki czemu możemy teraz wywoływać metody ciągów w krótki sposób. Zróbmy to!

Teraz gsubjest ponownie wzywany, aby zastąpić wszystko z powrotem szaleństwem. Ten czas %djest używany zamiast .wzorca zastępczego, ponieważ nasza funkcja może i musi przetwarzać tylko liczby ( .spowodowałoby to błąd na liczbach ujemnych). Ta funkcja czasu ( loadponownie edytowana w celu zapisania bajtów) dodaje najpierw1 edytowana w swój pierwszy (i tylko) vaargument, konwertując go na pozycję w łańcuchu dict, a następnie zwraca znak z tej pozycji.

Brawo, już prawie!

Dramatyczny finał, czyli dlaczego nawiasy mają znaczenie

print((ABOVE))

Cóż… dlaczego w ogóle dwie pary nawiasów? Czas porozmawiać o paraleli ... eh, wielokrotny powrót do Lua. Chodzi o to, że jedna funkcja może zwrócić kilka wartości z jednego wywołania (spójrz na to meta-pytanie, aby uzyskać więcej przykładów).

W tym przypadku ostatnia gsubzwróciła dwie wartości: łańcuch odpowiedzi, którego potrzebujemy, i liczbę wykonanych wymian (liczba cyfr faktycznie, ale kogo to obchodzi). Gdyby nie para wewnętrzna, wydrukowano by zarówno łańcuch, jak i numer, co nas popsuło. Dlatego poświęcamy dwa bajty, aby pominąć drugi wynik i ostatecznie wydrukować produkt tej fabryki szaleństwa.


Cóż, podobało mi się wyjaśnianie prawie tak samo jak gra w golfa, mam nadzieję, że wiesz, co się tutaj dzieje.

val mówi Przywróć Monikę
źródło
Uwaga: przechodzi wszystkie przypadki testowe, ale w innych prawdopodobnie prawdopodobnie zaokrągla się niepoprawnie. Jeśli możesz go znaleźć, naprawię go.
val mówi Przywróć Monikę