Aksesori setelah fakta!

10

Tantangan ini terinspirasi oleh Matematika adalah fakta. Pemrograman tidak .


Notasi matematika untuk faktorial, atau fakta adalah tanda seru !. Tanda seru juga merupakan simbol umum untuk notbanyak bahasa pemrograman.

Tantangan:

Ambil string, berisi angka, dan karakter: + !sebagai input dan output sebagai berikut:

Segala sesuatu di depan tanda seru harus dievaluasi sebagai ekspresi matematika, demikian 2+2juga halnya 4.

Segala sesuatu setelah tanda seru harus ditambahkan sebagai aksesori untuk apa pun yang ada di depannya, jadi: 2+2!5harus memberi 45, karena 2+2=4, dan 5merupakan aksesori. 2+2!5+5harus memberi 410.

Karena !juga berarti not, apa pun yang bukan aksesori setelah fakta tidak boleh ditambahkan. Jadi, 2+2!!5harus memberi 4, karena 5bukan aksesori. Sekarang, not(not(true))==truejadi 2+2!!!5harus memberi 45. 2+2!!5!5+5harus memberi:, 410karena 2+2=4, kemudian diikuti oleh faktorial dan !5!5+5. Yang pertama 5bukan fakta, tetapi 5+5setelah tanda seru lain, dan karena itu fakta, lagi.

Klarifikasi:

  • Tanda seru tidak akan berdekatan dengan tanda +di kedua sisi.
  • Tidak akan ada yang memimpin +untuk angka (itu 5, tidak +5).
  • Anda dapat memasukkan nol di depan jika itu adalah hasil dari ekspresi di depan yang pertama !. Keduanya 4dan 04diterima sebagai input:0+0!4

Ringkasan eksekutif: mengevaluasi setiap jumlah (memperlakukan !sebagai pemisah). Kemudian buang semua angka yang muncul setelah angka genap !(dihitung dari awal string). Lalu hapus semua !.

Kasus uji:

!
   <- Empty string

5
5

12!
12

!87
87

!!5
   <- Empty string

5+5!2+2
104

5+5!!2+2
10

1!2!3!4!5!6!7!8!9
12468

10+10!!2+2!!3+3!4+4
208

2!!3!5
25

2!!3!5!7
25

10!!!!!!!5
105

Ini adalah sehingga kode terpendek dalam byte (dalam setiap bahasa) menang! Penjelasan sangat dianjurkan!

Stewie Griffin
sumber
umm ... katakanlah kita memiliki 2 !! 3! 5 di sini ada atau tidak 5 aksesori dari 3?
officialaimm
3
@officialaimm Ini 25(lihat test case tambahan). Yang lebih penting 2!!3!5!7masih akan memberi 25, karena ada jumlah genap !kiri 7(jadi Anda tidak hanya menghitung run tepat di depan nomor, tetapi semua !kiri itu).
Martin Ender
Bisakah hasilnya berupa Mathematica Row?
ngenisis
Um ... jadi tantangan ini sebenarnya tidak ada hubungannya dengan faktorial?
DLosc

Jawaban:

5

Retina , 35 31 29 byte

Disimpan 4 byte dengan mengambil beberapa inspirasi dari produk ETH .

Terima kasih kepada Leo karena telah menyimpan 2 byte lagi.

\d+|\+
$*
1+
$.&
1`!

!\d*!?

Cobalah online!

Martin Ender
sumber
Anda dapat menyimpan beberapa byte di baris terakhir seperti ini
Leo
1
@ Leo Itu benar-benar rapi, terima kasih. :)
Martin Ender
5

JavaScript (ES6), 58 56 byte

Disimpan dua byte berkat Martin Ender .

let f =
x=>x.replace(/[^!]+/g,eval).replace(/!(\d*)!?\d*/g,"$1")
<input value="2+2!5+5" oninput="try{O.value=f(value)}catch(e){}"><br>
<input id=O value="410" disabled>

Mungkin ditingkatkan entah bagaimana ...

Produksi ETH
sumber
Penggunaan argumen fungsi yang bagus replace.
Neil
@Neil Terima kasih, tapi saya menemukan cara yang lebih baik :-)
ETHproduksi
Cuplikan kode Anda memberi saya jawaban yang salah 1+1!5. Saya pikir Anda lupa evalsedikit sebelum !.
Nilai Tinta
@ ValueInk Ah sial, saya tidak berpikir ada cara mudah untuk memperbaikinya.
ETHproduksi
2

Jelly , 16 byte

ṣ”!µḢW;m2$VṾ$L¡€

Cobalah online!

Penjelasan

Pengamatan utama di sini adalah bahwa kita dapat menjalankan langkah "out of order"; alih-alih mengevaluasi jumlah kemudian mengabaikan yang tidak kita sukai, kita dapat mengabaikan jumlah dalam posisi yang tidak valid, lalu mengevaluasi sisanya.

ṣ”!µḢW;m2$VṾ$L¡€
ṣ”!                Split input on '!'
   µ               Set as the new default for missing arguments
    Ḣ              Take the first element, removing it from the default
     W;  $         Cons with
       m2            every odd-numbered element of {the tail of the !-split input}
               €   For each remaining element
          VṾ$      Evaluate and de-evaluate it
             L¡      a number of times equal to its length

Mengevaluasi jumlah seperti "10+10"akan mengevaluasinya ke angka, misalnya 20, kemudian mengevaluasinya menjadi string "20",. Mengulangi proses itu tidak memiliki efek tambahan (ini idempoten). Dengan demikian, kami secara efektif mengevaluasi setiap elemen string, kecuali string nol, yang tetap tidak dievaluasi karena memiliki panjang nol.


sumber
Itu trik yang bagus untuk mengevaluasi setiap item secara kondisional. Bisakah Anda mengambil logika AND dari setiap item dan nilainya eval-deval'd? (Saya berasumsi string kosong itu salah dalam Jelly)
ETHproduksi
@ ETHproductions: Jelly's tacitness membuatnya tidak mungkin menghemat byte; itu lebih suka untuk menghindari menggunakan nilai yang sama dua kali jika memungkinkan, dan jika Anda ingin menggunakan kembali nilai, Anda biasanya harus setidaknya meletakkan ekstra µdi suatu tempat (dan µtidak bekerja di dalam satu lingkaran, yang berarti bahwa Anda akan memerlukan sesuatu bahkan lebih verbose). Saya berhasil membuatnya bekerja, seperti ṣ”!µḢW;m2$ȧVṾ$$€, tetapi tidak lebih pendek (dan memiliki tumpukan tanda-tanda dolar yang cenderung terjadi ketika Anda mendorong Jelly ke tepi kemampuannya untuk bersarang di struktur kontrol.)
2

Jelly , 18 byte

ṣ”!µḊm2;@ḢW$LÐfVṾ€

Cobalah online!

Bagaimana?

ṣ”!µḊm2;@ḢW$LÐfVṾ€ - Main link: string
ṣ”!                - split on '!' characters
   µ               - monadic chain separation (call that x)      e.g. ['1+1','0+0','0+0','0+0','','1+0','','','']
    Ḋ              - dequeue x (all but the leftmost entry of x) e.g.       ['0+0','0+0','0+0','','1+0','','','']
     m2            - modulo 2 index into that result             e.g.       ['0+0',      '0+0',   '1+0',   '']
           $       - last two links as a monad
         Ḣ         -     head x (the leftmost entry of x)        e.g.  '1+1'
          W        -     wrap                                    e.g. ['1+1']
       ;@          - concatenate with reversed arguments         e.g. ['1+1','0+0',      '0+0',   '1+0',   '']
             Ðf    - filter keep:
            L      -     length (keep that have non-zero length) e.g. ['1+1','0+0',      '0+0',   '1+0']
               V   - eval as jelly code (vectorises)             e.g. [  2,    0,          0,       1]
                      Yes, addition is just + and decimal numbers are just strings of digits in Jelly believe it or not!
                Ṿ€ - uneval €ach (creates a string from each one)e.g. [ '2',  '0',        '0'     ,'1']
                      without the € it would uneval the list and hence yield commas too)
                   - implicit print (prints the resulting list [of characters and possibly
                      lists of characters] as if it were all one string.)
Jonathan Allan
sumber
Saya tidak berpikir ini berfungsi untuk literal 0+0di tengah input (di tempat di mana tidak dibuang); menghasilkan string nol, meskipun harus menghasilkan angka 0.
Ah, benar - saya harus pindah ke solusi yang lebih lama :(
Jonathan Allan
Harus diperbaiki (mungkin golf sekarang).
Jonathan Allan
1

Ruby , 58 56 + 1 = 59 57 byte

Menggunakan -pbendera. -2 byte dari Tutleman .

i=0;$_=' '+$_;gsub(/!?([^!]*)/){eval$1if(2>i+=1)||i%2<1}

Cobalah online! (Baris kode tambahan ditambahkan sehingga akan mengambil semua jalur input dan mencetak output di jalur yang berbeda.)

Nilai Tinta
sumber
Saya pikir Anda bisa menjatuhkan tanda kurung eval$1, bukan?
Tutleman
@ Talkleman ya. Saya tidak tahu masalah apa yang saya alami yang membuat saya menambahkan parens (mereka tidak ada ketika saya mulai menulis program), tetapi sepertinya saya benar-benar dapat menghentikannya.
Nilai Tinta
0

Batch, 192 184 byte

@echo off
set/ps=
call:c . "%s:!=" "%"
echo(%s%
exit/b
:c
set s=
if not %2=="" set/as=%2
:l
shift
shift
if "%1"=="" exit/b
if %1=="" goto l
set/at=%1
set s=%s%%t%
goto l

Harus menangani string kosong tidak nyaman.

Neil
sumber
0

Pip , 18 byte

Saya pikir ini adalah yang terpendek yang didapat ... meskipun saya mengatakan itu sekitar tiga iterasi yang lalu juga.

{VaX++v%2+!v}Ma^'!

Mengambil input sebagai argumen baris perintah. Cobalah online!

Penjelasan

                    a is 1st cmdline arg; global variable v is -1 (implicit)
              a^'!  Split a on !
{           }M      Map this function to the resulting list (note that inside function,
                    a is the function arg):
    ++v              Increment v (so that v tracks the 0-based index of the current
                     element)
       %2            We want to keep the elements where v%2 is 1...
         +!v         ... and also v=0, where v%2 is 0, but adding !v makes it 1
  aX                 String-multiply the argument by the above quantity (turning elements
                     we don't want into empty string)
 V                   Eval it (eval'ing empty string gives nil, but that's okay because
                     nil doesn't output anything)
                    Autoprint the resulting list, concatenated together (implicit)
DLosc
sumber
0

R, 95 byte

function(x)for(e in strsplit(gsub('!([^!]*)![^!]*','\\1!',x),'!')[[1]])cat(eval(parse(text=e)))

Mungkin ada beberapa ruang untuk perbaikan tetapi saat ini adalah yang terbaik yang bisa saya lakukan.

Robert Hacken
sumber