นิพจน์ที่เท่ากับความยาว


14

กำหนดตัวเลขให้หานิพจน์ด้วยคำที่เท่ากับจำนวนนั้นด้วยความยาวของตัวเลขนั้น

ดังนั้นสำหรับอินพุต15คุณอาจส่งออกsixteen minus oneซึ่งมีสิบห้าอักขระ (ไม่นับช่องว่าง) หากมีหลายวิธีให้พิมพ์ตามที่คุณต้องการ หากไม่มีอยู่ให้พิมพ์impossible

ใช้เฉพาะผู้ประกอบการplus, minus, และtimes divided byผู้ประกอบการประเมินจากซ้ายไปขวา

one thousand two hundred thirty fourรูปแบบเป็น 1234 สังเกตว่าไม่มี "และ" และไม่มีเครื่องหมายขีดกลางหรือเครื่องหมายจุลภาค

อินพุตและตัวเลขทั้งหมดที่ใช้ในเอาต์พุตต้องเป็นจำนวนเต็มบวกน้อยกว่า 10,000

อินพุตจะถูกกำหนดเป็นอาร์กิวเมนต์บรรทัดคำสั่ง พิมพ์ไปยังเอาต์พุตมาตรฐาน

ตัวอย่าง

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
จำนวนเต็มไม่ใช่ค่าลบ? So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.คุณอาจต้องการยกเว้นศูนย์ แล้วแต่คุณ.
เลเวลริเวอร์เซนต์

@ สตีฟเวอร์ริลล์จุดดี; ฉันเปลี่ยนเป็น "จำนวนเต็มบวก"
Ypnypn

4
ดังนั้น ... one hundred three times one times one times one times one times one times one times one times one times one times one times oneถูกต้อง?
Qwix

@Qwix ใช่; คำตอบที่น่าเบื่อเป็นที่ยอมรับ แต่ที่หนึ่งไม่ทำงานสำหรับ 104, 105, 106, 107, 108, 109, 110 หรือ 111
Ypnypn

คำตอบ:


1

Javascript, 434 ตัวอักษร

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

ให้ฟังก์ชันในเนมสเปซส่วนกลางSซึ่งยอมรับจำนวนเต็มใด ๆ ที่ไม่เป็นลบและส่งคืนสตริงที่ต้องการหรือ"Invalid"หากจำนวนเต็มไม่สามารถแทนค่าภายในข้อมูลจำเพาะ

ฉันดูเหมือนจะใช้วิธีการเดียวกันกับ @optokopper โดยทำการสังเกตแบบเดียวกับที่"plus six plus nine"เป็นสตริงที่สั้นที่สุดและตัวเลขทั้งหมดที่มากกว่า 27 สามารถแสดงได้โดยการเชื่อมสตริงหนึ่งใน 15 ฐานเพื่อคัดลอกแผ่นของซ้ำ

ต้องบอกว่าตารางของสตริงฐานที่เราใช้แตกต่างกันและวิธีแก้ปัญหาของฉันขึ้นอยู่กับการทวิบิตและตัวดำเนินการส่วนที่เหลือ ( %) นอกจากนี้ยังรวมถึง"multiplied by"การดำเนินการที่เป็นไปได้ กลศาสตร์ของวิธีการสร้างสตริงนั้นแตกต่างกันอย่างสิ้นเชิงเนื่องจากความแตกต่างระหว่าง C และ Javascript

นั่นคือความพยายามที่ดีที่สุดของฉันในทุก ๆ อัตรา ;)

ขอขอบคุณเป็นพิเศษกับ @chiru ซึ่งการพูดคุยกันว่าตัวเลขใดที่สามารถทำได้ช่วยป้องกันการค้นหาที่ไร้ผล


22

JS, 1719/1694

ทฤษฎี

น่าเสียดายที่กฎที่คุณให้ไว้อาจไม่ใช่การตัดสินใจที่ชาญฉลาดจากมุมมองทางคณิตศาสตร์ ในความเป็นจริงการใช้กฎส่วนย่อยที่เล็กกว่านั้นคุณสามารถค้นหาวิธีแก้ปัญหาสำหรับทุกหมายเลขในช่วงเวลาที่กำหนด

ฉัน = [1;  10000]

ยกเว้น

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

ซึ่งไม่มีวิธีแก้ปัญหา

ชุดกฎที่ลดลง

พิจารณากฎย่อยต่อไปนี้:

  • ใช้เฉพาะผู้ประกอบการplus, และminustimes
  • คุณไม่จำเป็นต้องใช้หลายเหตุการณ์plusหรือminusในนิพจน์ของคุณ
  • คุณไม่จำเป็นต้องใช้ค่าdivisionมิได้operator associativity(เป็นชุดโซลูชั่นของพวกเขาได้รับการคุ้มครองแล้วโดยกฎข้อแรก)

เหตุผลที่ว่าทำไมงานนี้ก็คือว่าในขณะที่คุณกล่าวถึงก่อนหน้านี้ที่มี @Qwix คุณให้น่าเบื่อคำตอบ( times one)+$ที่เป็นสำนวนที่ว่าจุดสิ้นสุดในการแสดงออกปกติ การอนุญาตสิ่งนี้แต่ละหมายเลขในช่วงเวลาที่กำหนดจะมีทางออก

เมื่อคุณตอบในความคิดเห็นของคุณ

@Qwix ใช่; คำตอบที่น่าเบื่อเป็นที่ยอมรับแม้ว่าจะไม่สามารถใช้ได้กับ 104, 105, 106, 107, 108, 109, 110 หรือ 111

คุณพูดถูก: ไม่ได้ผลเมื่อคุณพยายามสร้างนิพจน์ของคุณโดยเริ่มจากตัวเลขเองone hundred four times one times one …หรือตัวเลขอื่น ๆ

อย่างไรก็ตามหากการแสดงออกของคุณเริ่มต้นด้วยการแสดงออกซึ่งการประเมินเท่ากับหนึ่งในตัวเลขที่กำหนดคุณจะโชคไม่ดี ตัวอย่างเช่นให้สังเกตว่า17 + 87เป็นจริง104ดังนั้นเราจึงสามารถเขียน104เป็น:

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

หากต้องการดูว่าชุดย่อยนี้ใช้งานได้ให้บันทึกไฟล์นี้num.jsและตรวจสอบให้แน่ใจว่าติดตั้ง SpiderMonkey ซึ่งเป็นเอ็นจิน JavaScript สำหรับบรรทัดคำสั่งบนระบบของคุณ

อัลกอริทึม

  • ให้เรากำหนดสถานที่Kสำหรับจำนวนเต็มบวกเป็นรัฐของจำนวนที่มีตัวอักษรและมีค่าของNN
  • ให้เรากำหนดคุณสมบัติเพิ่มเติมFสำหรับนิพจน์เนื่องจากสถานะของการแปลงคำ8kนั้น - สั้นกว่าการประเมินด้วย k ∈ℕ Fย่อมาจาก "fillable" และอธิบายหรือไม่ว่าเราสามารถเติมเต็มการแปลงคำในการแสดงออกที่มีการแสดงออกของความยาว 8 (คือ" times one") Nดังกล่าวว่าการแสดงออกที่เกิดอาจได้รับทรัพย์สิน

จากนั้นเราจะดำเนินการดังนี้:

  • แปลงหมายเลขอินพุตเป็นคำ
  • ตรวจสอบว่าหมายเลขอินพุตมีคุณสมบัติKหรือไม่
    • หากเป็นเช่นนั้นให้ส่งคืนคำ ( 4เป็นตัวเลขเดียวกับคุณสมบัตินี้ขออภัย)
    • หากไม่เป็นเช่นนั้นให้ดำเนินการต่อ
  • สำหรับนิพจน์สองตัวถูกดำเนินการทั้งหมด (ส่วนเพิ่มเติมการลบและการคูณในลำดับนี้) ที่ส่งผลให้หมายเลขอินพุตตรวจสอบว่าการประเมินของพวกเขามีคุณสมบัติKหรือไม่
    • ถ้าเป็นเช่นนั้นส่งคืนคำ
    • Nถ้ามันไม่ได้ตรวจสอบว่าการแสดงออกสองตัวถูกดำเนินการมีสถานที่ให้บริการ
      • หากเป็นเช่นนั้นให้เติมนิพจน์ด้วย" times one"และตรวจสอบว่าการประเมินผลของนิพจน์ที่เกิดขึ้นมีคุณสมบัติKหรือไม่
        • ถ้าเป็นเช่นนั้นส่งคืนคำ
        • หากไม่เป็นเช่นนั้นให้ดำเนินการต่อ
      • หากไม่เป็นเช่นนั้นให้ดำเนินการต่อ
  • ไปดื่มกาแฟ

การปฏิบัติ

num.js (สำหรับ SpiderMonkey / บรรทัดคำสั่ง)

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 (สำหรับเบราว์เซอร์)

โค้ดที่กำหนดจากด้านบนไม่สามารถใช้งานได้กับเบราว์เซอร์เนื่องจากคำสั่งสุดท้ายซึ่งคว้าอาร์กิวเมนต์บรรทัดคำสั่งเพื่อสร้างคำสั่งที่ดีจากสคริปต์ที่กำหนด

ในการเรียกใช้รหัส JavaScript โดยตรงจากภายในเบราว์เซอร์ของคุณให้เลือกรหัสข้างบนนี้:

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}

ตอนนี้วางลงในคอนโซล JavaScript ของเบราว์เซอร์เพื่อให้คุณสามารถสร้างผลลัพธ์เดียวกันจากภายในเบราว์เซอร์ของคุณด้วยตัวอย่างเช่น:

Y(1234);

ตัวอย่าง (บรรทัดคำสั่ง)

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

และเพื่อดูเคล็ดลับที่คุณสามารถทำให้ตัวเลขแต่ละตัวทำงานได้เพียงดูคำตอบที่น่าเบื่อสำหรับ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

รหัสที่จัดทำขึ้นจะสร้างโซลูชันที่ถูกต้องสำหรับช่วงเวลาที่กำหนด (และอาจสูงกว่านั้นคุณต้องเพิ่มค่าของตัวแปรL)

สถิติ

ฉันสนใจ " นิพจน์ที่น่าเบื่อ " (หรือ: ใช้สตริงย่อยtimes oneต่อนิพจน์ภายในอัลกอริทึมนี้เท่าใด) เนื่องจากส่วนนี้มีหน้าที่ในการค้นหาวิธีแก้ปัญหาสำหรับทุกจำนวนภายในช่วงเวลาที่กำหนด ดูตัวเอง:

x : นิพจน์ที่ n (ต่ำสุด 0, สูงสุด 10,000)

y : จำนวนสตริงย่อย "คูณหนึ่ง" ภายในนิพจน์ (ต่ำสุด 0, สูงสุด 1245)

กราฟ

สรุป:

  • การแสดงออกมีแนวโน้มที่จะได้รับน่าเบื่อมากขึ้นในลักษณะเชิงเส้น
  • โซลูชันกว่า 99% นั้นน่าเบื่อ

2
วิธีแก้ปัญหาสำหรับ 4 มีอยู่four
FUZxxl

@FUZxxl ฉันไม่เคยปฏิเสธ ในกรณีที่คุณตอบกลับIf it does, return the words (4 is the only number with this property, unfortunately)คุณอาจเข้าใจผิดในส่วนนี้ มันบอกว่า4เป็นนิพจน์ที่ไม่มีโอเปอเรเตอร์เท่านั้นที่สร้างโซลูชันของตัวเอง
Chiru

@FUZxxl โอ้ไม่เป็นไร ฉันเพิ่งเห็นว่าในส่วนเริ่มต้นฉันบอกว่าไม่มีวิธีแก้ปัญหาใน X = [0; 10] ∪ {12} แม้ว่าต่อมาฉันพูด4ได้ว่ามีทางออก ฉันแก้ไขช่วงเวลาขอบคุณ :)
Chiru

6

C, 450 ตัวอักษร

แก้ไข: ลบแล้ว zero

แก้ไข: ใช้เท่านั้น plusและminus

ฉันค้นหาการแสดงออกที่สั้นที่สุดที่เพิ่มตัวอักษรและทำให้สภาพเป็นจริง ฉันพบplus ten plus fiveมีความยาว 15 และเพิ่ม 15 กับสตริง

ฉันต้องการเพียงการแสดงออกสำหรับ 15 หมายเลขแรกที่ไม่สามารถทำได้เพื่อแสดงจำนวนที่เป็นไปได้ 12 เป็นตัวเลขที่เป็นไปไม่ได้ที่ใหญ่ที่สุดดังนั้นจึงเพียงพอสำหรับหมายเลข hardcode ที่เล็กกว่า 28

4 = สี่
11 = หกบวกห้า
13 = แปดบวกห้า
14 = ยี่สิบลบหก
15 = ยี่สิบลบห้า
ต 16 = สิบแปดลบสอง
17 = สิบสี่บวกสาม
ต 18 = ยี่สิบสองลบสี่
20 = สามสิบสองลบสิบสอง
21 = ยี่สิบบวกสองลบหนึ่ง
22 = ยี่สิบบวกสี่ลบสอง
23 = สามสิบลบแปดบวกหนึ่ง
24 = ยี่สิบบวกแปดลบสี่
25 = ยี่สิบบวกแปดลบสาม
27 = ยี่สิบแปดลบหกบวกห้า

เราสามารถเขียนทุกหมายเลข> 27 เป็น x * 15 + หนึ่งในหมายเลขด้านบน

แข็งแรงเล่นกอล์ฟ

#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");}

รหัสที่อ่านได้

#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
ไม่แน่ใจว่าวิธีการทำงานของรหัสของคุณ แต่เนื่องจากคำถามระบุว่าall numbers used in the output must be positive integersคุณสามารถลบออก#define Z "zero"จากรหัสของคุณพร้อมกับอินสแตนซ์ของ Z เนื่องจากคุณไม่ควรใช้หรือไม่
Qwix

"บวกสิบสอง" คือ 12 ตัวอักษร นั่นจะช่วยทำให้รหัสของคุณสั้นลงไหม
isaacg

ฉันจะทำให้มันสั้นกว่าplus twelve
อนึ่ง

ตกลงฉันอ่านผิดกฎ
isaacg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.