Lihat ibu! Saya membuat sistem angka (Basis 10) saya sendiri! [Tutup]

21

Kita semua pernah melakukannya, yah, mungkin tidak, tetapi membuat bahasa asing Anda sendiri dan sistem penomoran adalah pokok dari penulisan fantasi, tetapi sebagian besar hanya kegiatan yang menyenangkan.

Tugasnya sederhana, ambil dua input:

  1. Input daftar yang diurutkan terdiri dari 10 [sepuluh] 'angka' unik (setiap karakter ASCII yang dapat dicetak) dan menafsirkannya, secara berurutan, sebagai nilai 0, 1, 2, 3, ..., 9

    + Ada pengecualian untuk apa yang bisa menjadi angka di sini. Operator aritmatika (+, -, *, /), Tanda kurung, dan spasi tidak dapat digunakan sebagai salah satu angka.

  2. Masalah aritmatika hanya menggunakan 'angka'

Dan output hasil bilangan bulat setara dalam bentuk yang diberikan.

Ini sebuah contoh:

INPUT

abcdefghij

bcd + efg + hij
OUTPUT

bdgi

Dalam contoh, daftar input (Anda dapat memilih bentuk daftar) dari 'abcdefghij' yang sesuai dengan '0123456789' seperti 'hjkloiwdfp' juga akan sesuai 1 dengan 1 dengan '0123456789' di mana alih-alih 'a' yang dikaitkan dengan nol, 'h' tidak. Berikut aritmatika 'diterjemahkan' ke 123 + 456 + 789, yang sama dengan 1368. Ini kemudian harus dikeluarkan dalam bentuk yang kami berikan, jadi b (yang mewakili 1) d (untuk 2) g (untuk 6) dan i (untuk 8).

KASUS UJI

abcdefghij
abc + def - ghij

-gedc
qwertyuiop
qwerty / uiop

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

y9|8

LEBIH BANYAK ATURAN

  • Lubang Standar dilarang!
  • Ini kode golf, jadi jawaban tersingkat dalam byte menang.
  • Harus berupa program atau fungsi lengkap yang mengambil input dan output dalam format apa pun yang paling cocok untuk Anda. (Tidak bisa menambahkan informasi tambahan dalam input, cukup 'angka' dan ekspresi.
  • Gunakan bahasa apa pun yang Anda suka (asalkan sesuai dengan aturan lain)
Bill W
sumber
9
Kasus uji kedua menunjukkan bahwa hasil akhir dibulatkan, jika tidak hasilnya akan jadi q.ioiopewioyetqorw.... Jika demikian, pembulatan seperti apa yang harus diterapkan?
Arnauld
2
Untuk menambah poin @ SriotchilismO'Zaic, kami juga memiliki kotak pasir untuk keuntungan Anda dan kami; tujuannya adalah untuk membiarkan komunitas membantu memperbaiki tantangan sebelum diposting. Ide bagus untuk tantangan!
Giuseppe
3
Bahasa yang berbeda cenderung mengevaluasi persamaan yang sama secara berbeda, saya tidak yakin ada cara lain. Misalnya, T-SQL mengembalikan 1untuk 5/3, bukan 2, karena pembagian bilangan bulat (bukan pembulatan). Ini tidak membatalkan tantangan, tetapi Anda mungkin harus mengizinkan jawaban yang berbeda untuk kasus uji yang sama (lihat jawaban T-SQL saya di bawah).
BradC
2
@ Giuseppe Wow, saya sudah melihat-lihat tumpukan ini untuk waktu yang lama dan tidak pernah tahu itu! Pasti akan sangat membantu, terutama sebagai poster pertama kali (pendengar lama) bahwa saya. Akan mencatat untuk waktu berikutnya! Terima kasih atas komentar dan jawaban Anda.
Bill W
2
Variasi yang menarik untuk ini adalah yang mendukung basis angka apa pun, tergantung pada panjang string pertama dalam input ...
Darrel Hoffman

Jawaban:

11

05AB1E , 10 9 byte

žh‡.Eò¹Åв

(Sekarang) ditampilkan sebagai daftar karakter.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

          # 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)

Versi baru dari build 05AB1E adalah build di Elixir . The .Efungsi akan memanggil call_unary(fn x -> {result, _} = Code.eval_string(to_string(x)); result end, a), di mana Code.eval_stringadalah builtin Elixir .

Perhatikan bahwa versi lawas 05AB1E tidak akan berfungsi untuk ini, karena ini dibangun dengan Python. Angka-angka dengan 0s depan tidak akan dievaluasi:
Lihat semua kasus uji dalam versi lawas (yang menggunakan versi 10-byte karena Åвbuiltin baru).

Kevin Cruijssen
sumber
8

R , 58 byte

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

Cobalah online!

Menggunakan terjemahan karakter chartruntuk menukar digit, parses dan evalekspresi, lalu chartrkembali ke digit asli.

Jika pembulatan ke bilangan bulat terdekat diperlukan, ini

R , 65 byte

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

Cobalah online!

Giuseppe
sumber
Menggunakan [sebagai nama pendek untuk fungsi dengan 3 parameter sangat cerdas. Sudah selesai dilakukan dengan baik.
Robin Ryder
6

T-SQL, 117 byte

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

Jeda baris hanya untuk keterbacaan.

Input melalui tabel t yang sudah ada t dengan kolom teks c (karakter) dan e (persamaan), sesuai aturan IO kami .

Menggunakan fungsi SQL 2017 TRANSLATEuntuk beralih di antara karakter dan menghasilkan string yang tidak hanya berisi persamaan, tetapi kode untuk menerjemahkan kembali ke karakter asli:

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

String ini kemudian dievaluasi menggunakan EXEC().

Mungkin ada beberapa karakter (seperti satu kutipan ') yang akan memecahkan kode ini; Saya belum menguji semua karakter ASCII yang mungkin.

Per tantangan, saya mengevaluasi ekspresi seperti yang diberikan, tergantung pada bagaimana bahasa saya menafsirkan operator tersebut. Dengan demikian, test case kedua mengembalikan 1 ( w), dan bukan 2 ( e), karena pembagian bilangan bulat.

BradC
sumber
4

Perl 6 , 38 byte

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

Cobalah online!

Saya tidak yakin bagaimana pembulatan seharusnya bekerja. Jika putaran di akhir maka saya dapat menambahkan .rounduntuk 6 byte . Jika perilaku /harus berbeda maka mungkin lebih lama. Membawa input seperti kari f(arithmetic)(numerals)(arithmetic).

Penjelasan:

{                                    }  # 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
sumber
3

Stax , 74 66 65 byte

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

Jalankan dan debug itu

Stax tidak bekerja dengan baik di sini, tidak memiliki instruksi "eval" yang sebenarnya. Ini memiliki satu yang disebut "eval" dalam dokumen, tetapi hanya bekerja pada nilai-nilai literal, bukan ekspresi penuh.

rekursif
sumber
Ini mungkin tidak mematuhi prasyarat operator. Tidak yakin apakah itu diperlukan? staxlang.xyz/…
dana
@dana: Poin bagus. Saya tidak mempertimbangkan itu. Perbaikan kemungkinan akan memakan biaya beberapa byte, jadi saya akan menunggu klarifikasi sebelum mencoba mengubah perilaku itu.
Rekursif
3

Bash, 97 byte

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

Bisa jadi lebih kecil jika kita bisa memotong, daripada bulat. Juga sulit untuk menangani angka nol di depan (seperti dalam kasus uji # 2) karena angka Bash diinterpretasikan dimulai dengan 0 sebagai oktal.

berdesis
sumber
Apa konsensus tentang penggunaan utilitas seperti "bc" dan "tr" untuk bermain golf?
spuck
1
Saya bukan ahli, tapi saya pikir jawaban semacam itu biasanya diajukan sebagai sesuatu seperti "bash + coreutils"
Giuseppe
@ Giuseppe tradalah bagian dari coreutils, sementara bctidak. Meskipun demikian, bcini adalah alat yang sangat umum. Setiap perintah lain dalam jawaban ini adalah bash.
rexkogitans
-7 byte dicuri dari jawaban @ CM, mengurangi '0123456789' menjadi '0-9'
spuck
Mendefinisikan T tidak lagi menguntungkan: $Thanya satu byte lebih pendek dari 0-9, Anda hanya menggunakannya dua kali, dan Anda menghabiskan 8 byte untuk mendefinisikannya.
ruds
2

Bean , 94 90 byte

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]
)

Penjelasan

Program ini secara implisit menetapkan input baris pertama dan kedua sebagai string ke variabel adan bmasing - masing.

Setiap karakter cpada baris bdiganti dengan indeks masing-masing ikarakter yang ditemukan pada baris a, atau karakter itu sendiri jika tidak ditemukan.

Kemudian ia menghapus setiap urutan satu atau lebih 0yang didahului oleh batas dari string yang dihasilkan. Ini untuk mencegah eval()dari mengevaluasi urutan angka yang dimulai dengan 0sebagai oktal literal.

Setelah eval()dan Math.round(), hasilnya dipaksa kembali ke string dan setiap karakter digit idiganti oleh karakter yang sesuai dari garis apada indeks i.

Uji Kasus

Demo

abcdefghij
abcd + efg + hij

bdgi

Demo

abcdefghij
abc + def - ghij

-gedc

Demo

qwertyuiop
qwerty / uiop

e

Demo

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

y9|8
Patrick Roberts
sumber
2

Perl 5 -p , 63 byte

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

Cobalah online!

Mengambil ekspresi pada baris input pertama dan daftar terjemahan pada baris kedua.

Xcali
sumber
1

Perl 5 , 130 byte

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}

Cobalah online!

Mungkin double eval itu entah bagaimana bisa diubah menjadi s/.../.../geer.

Kjetil S.
sumber
1

Arang , 14 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Catatan: Ekspresi dievaluasi sesuai dengan semantik Python 3, jadi misalnya memimpin nol pada angka bukan nol adalah ilegal. Penjelasan:

   ⭆η           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
sumber
Sayangnya 0s terkemuka tidak bekerja di Python, yang ada dalam kasus uji.
Jonathan Allan
0

Python 3 , 137 byte

Pendekatan non-regex menggunakan str.translatedan str.maketransuntuk mengganti karakter. Saya kehilangan banyak karakter pada pemangkasan nol terkemuka ...

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))

Cobalah online!

Gábor Fekete
sumber
0

Python 3 , 167 byte

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)

Cobalah online!

Kamar untuk perbaikan ...

movatica
sumber
Masih gagal pada kasus uji terakhir: tio.run/…
ruohola
0

Bahasa Wolfram (Mathematica) , 121 byte

Saya mendefinisikan fungsi murni dengan dua argumen. Karena beberapa fungsi diulang, saya menyimpannya dalam variabel untuk menyimpan beberapa karakter. Kode ini hanya melakukan beberapa penggantian string dan kemudian gunakan ToExpressionuntuk mengevaluasi ekspresi dengan kernel Wolfram.

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

Cobalah online!

MannyC
sumber
0

Lua , 162 151 150 byte

  • -11 byte berkat ide saya untuk menggunakan load bukannyafunction(...) end
  • -1 byte dengan menghilangkan baris baru
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)')))

Cobalah online!

Bukan hal yang terpendek di dunia (Lua memaksa Anda untuk menjadi mewah cukup keras, terutama dengan kata kunci besar), tetapi cukup menyenangkan untuk dibuat. Program penuh mengambil input sebagai argumen dan hasil pencetakan.

Penjelasan

pengantar

l,p=...

Tetapkan nilai dari argumen ke variabel. Kamus kami adalah ldan ekspresip .

Ekspresi berikut ini cukup sulit untuk dipahami karena memiliki urutan eksekusi yang aneh, jadi saya akan menjelaskannya langkah demi langkah:

Mengonversi ke angka normal

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

Lakukan penggantian pada string ekspresi: ambil setiap simbol dan berikan fungsinya (load terbukti sendiri lebih pendek dari deklarasi normal di sini).

Fungsi menemukan posisi kemunculan dalam string dict untuk simbol yang diteruskan menggunakan find. ...adalah argumen pertama (dan satu-satunya) di sini karena kita berada dalam fungsi vaarg (salah loadsatunya adalah) yang merupakan simbol kita saat ini. Argumen berikut diperlukan untuk membuat findabaikan simbol khusus ( 1hanya nilai pendek yang mengevaluasi trueketika dikonversi ke boolean): posisi awal (satu default di sini) dan plain, yang sebenarnya menonaktifkan penanganan pola. Tanpa program tersebut gagal pada kasus uji ketiga karena %menjadi istimewa.

Jika kecocokan ditemukan, kurangi satu karena string Lua (dan array btw) berbasis 1. Jika tidak ada kecocokan yang ditemukan, itu tidak akan menghasilkan apa-apa, sehingga tidak ada penggantian yang dilakukan.

Memecahkan

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

Lanjutkan returnke ekspresi kami untuk membiarkannya mengembalikan hasil, menghitungnya dengan mengkompilasi sebagai fungsi Lua dan memanggilnya, melakukan pembulatan ( ini sebaliknya untuk membuatnya lebih pendek).

Pada akhirnya kami mendapatkan solusi numerik untuk masalah kami, hanya mengubahnya kembali tetap.

Membuatnya gila lagi

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

Baris pertama adalah cara pendek untuk mengubah angka menjadi string, jadi sekarang kita dapat memanggil metode string dengan cara singkat. Ayo lakukan!

Sekarang gsubdipanggil lagi untuk mengganti semuanya kembali menjadi gila. Waktu %dini digunakan .sebagai pengganti pola karena fungsi kami mungkin dan harus memproses hanya angka ( .akan mengakibatkan kesalahan pada angka negatif). Fungsi waktu ini ( loaded lagi untuk menyimpan byte) pertama-tama menambah 1ke vaargument pertama (dan satu-satunya), mengonversinya ke posisi dalam string dict, kemudian mengembalikan karakter darinya pada posisi itu.

Hore, hampir sampai!

Final dramatis, atau Mengapa Masalah Kurung

print((ABOVE))

Nah ... mengapa dua pasang kurung? Sudah waktunya untuk berbicara tentang kesetaraan ... eh, banyak kembali di Lua. Masalahnya adalah bahwa satu fungsi dapat mengembalikan beberapa nilai dari satu panggilan (lihat pertanyaan meta ini untuk lebih banyak contoh).

Di sini, yang terakhir gsubmengembalikan dua nilai: string jawaban yang kita butuhkan dan jumlah penggantian yang dilakukan (hitungan digit sebenarnya, tetapi siapa yang peduli). Jika bukan karena pasangan internal, baik string dan nomor akan dicetak, mengacaukan kami. Jadi di sini kita mengorbankan dua byte untuk menghilangkan hasil kedua dan akhirnya mencetak produk dari pabrik gila ini.


Yah, saya senang menjelaskan hampir sebanyak bermain golf, semoga Anda tahu apa yang terjadi di sini.

val mengatakan Reinstate Monica
sumber
Catatan: ini melewati semua testcases, tetapi mungkin putaran salah di yang lain. Jika Anda dapat menemukannya, saya akan memperbaikinya.
val berkata Reinstate Monica