Ekspresi yang sama dengan panjangnya


14

Diberi nomor, temukan ekspresi dalam kata-kata yang menyamai angka itu, dengan panjang angka itu.

Jadi, untuk input 15, Anda dapat menampilkan sixteen minus one, yang memiliki lima belas karakter (tidak termasuk spasi). Jika ada beberapa solusi, cetak mana yang Anda inginkan. Jika tidak ada, cetakimpossible

Gunakan hanya operator plus, minus, times, dan divided by. Operator dievalutasi dari kiri ke kanan.

Format 1234 sebagai one thousand two hundred thirty four. Perhatikan tidak adanya "dan", dan tidak ada tanda hubung atau koma.

Input dan semua angka yang digunakan dalam output harus bilangan bulat positif kurang dari 10.000.

Input akan diberikan sebagai argumen baris perintah. Cetak ke keluaran standar.

Contohnya

1: impossible
4: four
7: impossible
13: eight plus five (you could also output "five plus eight")
18: one plus two times six (note that operators are evaluated from left to right)
25: one thousand divided by forty

4
bilangan bulat negatif? So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.Anda mungkin ingin mengecualikan nol. Terserah kamu.
Level River St

@steveverrill Poin bagus; Saya telah mengubahnya menjadi "bilangan bulat positif".
Ypnypn

4
sooo ... one hundred three times one times one times one times one times one times one times one times one times one times one times onevalid?
Qwix

@ Kwik Ya; jawaban yang membosankan dapat diterima, meskipun jawaban itu tidak berlaku untuk 104, 105, 106, 107, 108, 109, 110, atau 111.
Ypnypn

Jawaban:


1

Javascript, 434 karakter

function f(s){return s.replace(/[A-Z]/g,function(t){return{O:'one',T:'two',H:'three',F:'four',I:'five',S:'six',E:'seven',G:'eight',N:'nine',Z:'ten',P:' plus ',M:' minus ',U:' times ',X:'teen',A:'thir',B:'twenty'}[t]})}A='TPAX|GeenMT|EXUO|B FMS|F|GPSUT|ZPHPG|BPFMT|AXPFPS|BPGMF|EUOPGeen|NPT|B GMSPI|GPI|EPE'.split('|');O=26640;function S(n){return n<15&&!(O>>n&1)?'Invalid':f(A[v=n%15])+(new Array(~~(n/15)+(O>>v&1))).join(f('PSPN'))}

Menghasilkan fungsi dalam namespace global S,, yang menerima bilangan bulat non-negatif dan mengembalikan string yang diperlukan, atau "Invalid"jika bilangan bulat tidak dapat diwakili dalam spesifikasi.

Saya kelihatannya telah menggunakan pendekatan yang sama dengan @optokopper, setelah melakukan pengamatan yang sama yaitu "plus six plus nine"string padding terpendek yang mungkin, dan bahwa semua angka lebih besar dari 27 dapat diekspresikan dengan menggabungkan satu dari 15 string dasar ke salinan berulang pad.

Karena itu, tabel string dasar yang kami gunakan berbeda, dan solusi saya bergantung pada sedikit twiddling dan operator sisanya ( %). Ini juga termasuk "multiplied by"operasi yang memungkinkan. Dan tentu saja mekanisme bagaimana string dibangun sangat berbeda karena perbedaan antara C dan Javascript.

Bagaimanapun, itu adalah upaya terbaik saya. ;)

Terima kasih khusus kepada @ chiru, yang pembahasannya tentang angka mana yang dapat dicapai membantu mencegah pencarian yang sia-sia.


22

JS, 1719/1694

Teori

Sayangnya, aturan yang Anda berikan mungkin bukan keputusan bijak dari sudut pandang matematika. Bahkan, menggunakan subset aturan yang lebih kecil, Anda dapat menemukan solusi untuk setiap angka dalam interval yang diberikan

I = [1;  10000]

kecuali untuk

X = [1;  3] ∪ [5;  10] ∪ {12}

yang tidak ada solusinya.

Set aturan yang dikurangi

Pertimbangkan subet aturan berikut:

  • Gunakan hanya operator plus, minusdan times.
  • Anda tidak perlu menerapkan beberapa kejadian plusatau minusdalam ekspresi Anda.
  • Anda tidak perlu mengimplementasikan keduanya divisionatau operator associativity(karena set solusi mereka sudah dicakup oleh aturan pertama).

Alasan mengapa ini berhasil adalah, seperti yang Anda diskusikan sebelumnya dengan @Qwix, Anda mengizinkan jawaban yang membosankan , yaitu, ekspresi yang diakhiri dengan ekspresi reguler ( times one)+$. Mengizinkan ini, setiap angka dalam interval yang diberikan akan memiliki solusi.

Ketika Anda menjawab di salah satu komentar Anda,

@ Kwik Ya; jawaban yang membosankan dapat diterima, meskipun jawaban itu tidak berlaku untuk 104, 105, 106, 107, 108, 109, 110, atau 111. -

Anda benar sekali: Ini tidak berfungsi ketika Anda mencoba membangun ekspresi Anda dimulai dengan angka itu sendiri, yaitu one hundred four times one times one …atau angka-angka lainnya.

Namun, jika ekspresi Anda dimulai dengan ekspresi yang evaluasinya sama dengan salah satu angka yang diberikan, Anda kurang beruntung. Misalnya, perhatikan itu 17 + 87memang 104, jadi kita bisa menulis 104sebagai:

104: seventeen plus eighty seven times one times one times one times one times one times one times one times one times one times one

Untuk melihat bahwa bagian ini berfungsi, simpan file ini sebagai num.js dan pastikan bahwa SpiderMonkey, mesin JavaScript untuk baris perintah, diinstal pada sistem Anda.

Algoritma

  • Mari kita mendefinisikan properti Kuntuk bilangan bulat positif sebagai keadaan angka yang memiliki Nhuruf dan memiliki nilaiN .
  • Mari kita lebih lanjut mendefinisikan properti Funtuk ekspresi sebagai keadaan konversi kata menjadi 8k-kali lebih pendek dari evaluasinya dengan k ∈ ℕ. Fsingkatan dari "dapat diisi" dan menjelaskan apakah kita dapat mengisi kata konversi dari ekspresi dengan ekspresi panjang 8 (yaitu " times one") sehingga ekspresi yang dihasilkan mungkin mendapatkan properti N.

Kami kemudian melanjutkan sebagai berikut:

  • Ubah nomor input menjadi kata-kata.
  • Periksa apakah nomor input memiliki properti K.
    • Jika ya, kembalikan kata-kata tersebut ( 4sayangnya hanya nomor yang memiliki properti ini).
    • Jika tidak, lanjutkan.
  • Untuk semua ekspresi dua operan (penambahan, pengurangan, dan perkalian dalam urutan ini) yang menghasilkan nomor input, periksa apakah evaluasinya memiliki properti K.
    • Jika ya, kembalikan kata-katanya.
    • Jika tidak, periksa apakah ekspresi dua operan memiliki properti N.
      • Jika ya, isi ekspresi dengan " times one"dan periksa apakah evaluasi ekspresi yang dihasilkan memiliki properti K.
        • Jika ya, kembalikan kata-katanya
        • Jika tidak, lanjutkan
      • Jika tidak, lanjutkan
  • Pergi minum kopi

Praktek

num.js (untuk SpiderMonkey / baris perintah)

function X(e,t){return e+": "+t}function P(e){var n,t;for(n=1;.5*e+(e%2===0?1:0)>n;++n){if(t=C.s(n)+" plus "+C.s(e-n),t.replace(/\s/g,"").length===e)return t;if(F(e,t)&&e>t.length)return G(e,t)}return!1}function M(e){var t,n;for(t=L;t>1;--t){if(0>t-e)return!1;if(n=C.s(t)+" minus "+C.s(t-e),n.replace(/\s/g,"").length===e)return n;if(F(e,n)&&e>n.length)return G(e,n)}return!1}function F(e,t){return(e-t.replace(/\s/g,"").length)%8===0}function G(r,t){var e,i=(r-t.replace(/\s/g,"").length)/8,n="";for(e=0;i>e;++e)n+=" times one";return t+n}function T(e){var t,n,r;if(F(e,C.s(e)))return G(e,C.s(e));for(t=1,n=1;t<Math.floor(Math.sqrt(e));++t){for(;e>tn;)++n;if(tn===e&&(r=C.s(t)+" times "+C.s(n),r.replace(/\s/g,"").length===e))return r}return!1}function Y(e){var n,r,t;return e===C.s(e).length?X(e,C.s(e)):(n=P(e))?X(e,n):(r=M(e))?X(e,r):(t=T(e),t?X(e,t):X(e,"impossible"))}var L=1e4,C=new function(){return this.o=["","one","two","three","four","five","six","seven","eight","nine"],this.t=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.T=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.s=function(e){return e?this.m(e):"zero"},this.m=function(e){return e>=1e6?this.m(Math.floor(e/1e6))+" million"+(e%1e6!==0?" "+this.Z(e%1e6):""):this.Z(e)},this.Z=function(e){return e>=1e3?this.h(Math.floor(e/1e3))+" thousand"+(e%1e3!==0?" "+this.h(e%1e3):""):this.h(e)},this.h=function(e){return e>99?this.o[Math.floor(e/100)]+" hundred"+(e%100!==0?" "+this.U(e%100):""):this.U(e)},this.U=function(e){return 10>e?this.o[e]:e>=10&&20>e?this.T[e-10]:this.t[Math.floor(e/10)]+(e%10!==0?" "+this.o[e%10]:"")},this};print(Y(0|arguments[0]))

num.js (untuk browser)

Kode yang diberikan dari atas tidak dapat berfungsi untuk browser karena perintah terakhirnya, yang mengambil argumen baris perintah untuk membuat perintah yang bagus dari skrip yang diberikan.

Untuk menjalankan kode JavaScript langsung dari dalam browser Anda, pilih bagian dari kode di atas:

function X(e,t){return e+": "+t}function P(e){var n,t;for(n=1;.5*e+(e%2===0?1:0)>n;++n){if(t=C.s(n)+" plus "+C.s(e-n),t.replace(/\s/g,"").length===e)return t;if(F(e,t)&&e>t.length)return G(e,t)}return!1}function M(e){var t,n;for(t=L;t>1;--t){if(0>t-e)return!1;if(n=C.s(t)+" minus "+C.s(t-e),n.replace(/\s/g,"").length===e)return n;if(F(e,n)&&e>n.length)return G(e,n)}return!1}function F(e,t){return(e-t.replace(/\s/g,"").length)%8===0}function G(r,t){var e,i=(r-t.replace(/\s/g,"").length)/8,n="";for(e=0;i>e;++e)n+=" times one";return t+n}function T(e){var t,n,r;if(F(e,C.s(e)))return G(e,C.s(e));for(t=1,n=1;t<Math.floor(Math.sqrt(e));++t){for(;e>tn;)++n;if(tn===e&&(r=C.s(t)+" times "+C.s(n),r.replace(/\s/g,"").length===e))return r}return!1}function Y(e){var n,r,t;return e===C.s(e).length?X(e,C.s(e)):(n=P(e))?X(e,n):(r=M(e))?X(e,r):(t=T(e),t?X(e,t):X(e,"impossible"))}var L=1e4,C=new function(){return this.o=["","one","two","three","four","five","six","seven","eight","nine"],this.t=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.T=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.s=function(e){return e?this.m(e):"zero"},this.m=function(e){return e>=1e6?this.m(Math.floor(e/1e6))+" million"+(e%1e6!==0?" "+this.Z(e%1e6):""):this.Z(e)},this.Z=function(e){return e>=1e3?this.h(Math.floor(e/1e3))+" thousand"+(e%1e3!==0?" "+this.h(e%1e3):""):this.h(e)},this.h=function(e){return e>99?this.o[Math.floor(e/100)]+" hundred"+(e%100!==0?" "+this.U(e%100):""):this.U(e)},this.U=function(e){return 10>e?this.o[e]:e>=10&&20>e?this.T[e-10]:this.t[Math.floor(e/10)]+(e%10!==0?" "+this.o[e%10]:"")},this}

Sekarang, rekatkan ke konsol JavaScript browser Anda, sehingga Anda dapat menghasilkan hasil yang sama dari dalam browser Anda dengan, misalnya:

Y(1234);

Contoh (baris perintah)

chiru@chiru ~ $ js num.js 28
28: fourteen plus fourteen times one
chiru@chiru ~ $ js num.js 7
7: impossible
chiru@chiru ~ $ js num.js 42
42: nine thousand sixty minus nine thousand eighteen

Dan untuk melihat trik yang dapat digunakan untuk membuat setiap angka berfungsi, lihat saja jawaban yang membosankan untuk js num.js 1337:

1337: ten plus one thousand three hundred twenty seven times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one

Kode yang diberikan menghasilkan solusi yang valid untuk interval yang diberikan (dan mungkin bahkan di atas, Anda hanya perlu menaikkan nilai variabel L).

Statistik

Saya tertarik pada "betapa membosankan " ekspresi itu (atau: seberapa banyak substring times onedigunakan per ekspresi dalam algoritma ini), karena bagian ini bertanggung jawab untuk menemukan solusi untuk setiap angka dalam interval yang diberikan. Lihat sendiri:

x : n-th ekspresi (min. 0, maks. 10.000)

y : jumlah kemunculan substring "kali satu" dalam ekspresi (min. 0, maks. 1245)

Grafik

Kesimpulan:

  • Ekspresi cenderung semakin membosankan dalam cara yang linier.
  • Lebih dari 99% solusi membosankan.

2
Solusi untuk 4 ada—four
FUZxxl

@ FuZxxl Saya tidak pernah menyangkal itu. Jika Anda merespons If it does, return the words (4 is the only number with this property, unfortunately), Anda mungkin salah memahami bagian ini. Dikatakan itu 4adalah satu-satunya ekspresi bebas operator yang membentuk solusinya sendiri.
Chiru

@ FuZxxl Oh, oke. Saya baru saja melihat bahwa di bagian awal, saya mengatakan bahwa tidak ada solusi di X = [0; 10] ∪ {12}, meski kemudian, saya katakan 4ada solusinya. Saya mengoreksi intervalnya, terima kasih. :)
Chiru

6

C, 450 karakter

Edit: dihapus zero

Edit: hanya menggunakan plusdanminus

Saya mencari ekspresi terpendek yang menambahkan karakter dan menjaga kondisi tetap benar. Saya menemukan plus ten plus five15 panjang dan menambahkan 15 ke string.

Saya hanya perlu ekspresi untuk 15 angka pertama yang bukan tidak mungkin, untuk menyatakan angka yang mungkin. 12 adalah angka mustahil terbesar, oleh karena itu cukup untuk angka hardcode yang lebih kecil 28.

4 = empat
11 = enam tambah lima
13 = delapan ditambah lima
14 = dua puluh minus enam
15 = dua puluh minus lima
16 = delapan belas dikurangi dua
17 = empat belas ditambah tiga
18 = dua puluh dua minus empat
20 = tigapuluh dua dikurangi dua belas
21 = dua puluh ditambah dua minus satu
22 = dua puluh ditambah empat dikurangi dua
23 = tiga puluh dikurangi delapan ditambah satu
24 = dua puluh ditambah delapan minus empat
25 = dua puluh ditambah delapan minus tiga
27 = dua puluh delapan dikurangi enam ditambah lima

Kita dapat menulis setiap angka> 27 sebagai x * 15 + salah satu angka di atas.

Golf

#define P" plus "
#define M" minus "
#define U"four"
#define F"five"
#define E"eight"
#define W"twenty"
#define A"ten"P F P
*e[]={0,0,0,0,U,0,0,0,0,0,0,F P"six",0,E P F,W M"six",W M F,E"een"M"two",U"teen"P"three",W" two"M U,A U,"thirty two"M"twelve",W P"two"M"one",W M"two"P U,"thirty"P"one"M E,W P E M U,W M"three"P E,A F P"six",W" "E M"six"P F};main(n){n=atoi(1[(int*)1[&n]]);for(printf("%d: ",n);n>27;n-=15)printf(A);puts(e[n]?e[n]:"impossible");}

Kode yang Dapat Dibaca

#include <stdio.h>
#include <stdlib.h>

// add fifteen to string, both as value and as character count (without spaces)
const char *add_fifteen = "plus ten plus five";

// table with hardcoded expressions
// NOTE: we could calculate 19, 26, 28 and 29 from 4, 11, 13 and 14
// but we would need more logic, so we hardcode those 4 numbers too.
const char *expressions[30]={"impossible", "impossible", "impossible", "impossible",
    "four", "impossible", "impossible", "impossible", "impossible",
    "impossible", "impossible", "five plus six", "impossible",
    "eight plus five", "twenty minus six",
    "fourteen plus one", "eighteen minus two", "fourteen plus three",
    "twenty two minus four", "four plus ten plus five",
    "thirty two minus twelve", "nine plus seven plus five",
    "twenty plus four minus two", "twelve plus seven plus four",
    "twenty plus eight minus four", "twenty plus eight minus three",
    "five plus six plus ten plus five", "twenty eight minus six plus five",
    "eight plus five plus ten plus five", "seven plus seven plus ten plus five"};

int main(int argc,char *argv[])
{
    int n = strtol(argv[1], NULL, 0);
    int fifteens = 0;

    printf("%d: ", n);

    // how many times do we need to add fifteen?
    if(n>29){
        fifteens=(n/15) - 1;
        n -= fifteens*15; // ensure 30 > n >= 15, so we don't get "impossible"
    }

    // look up the expression for n
    printf("%s", expressions[n]);

    // add fifteens till we are done
    while(fifteens-- > 0) {
        printf(" %s", add_fifteen);
    }

    printf("\n");
    return 0;
}

2
Tidak begitu yakin bagaimana kode Anda bekerja, tetapi karena pertanyaannya menyatakan all numbers used in the output must be positive integers, dapatkah Anda menghapus #define Z "zero"dari kode Anda bersama dengan contoh Z karena Anda seharusnya tidak pernah menggunakannya?
Qwix

"ditambah dua belas" adalah 12 huruf. Apakah itu membantu mempersingkat kode Anda?
isaacg

Saya akan membuatnya lebih pendek, sayangnya spasi tidak masuk hitungan, plus twelvehanya 10 huruf
Optokopper

OK, saya salah membaca aturan.
isaacg
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.