長さに等しい式


14

数字が与えられたら、その数字の長さでその数字に等しい単語の式を見つけます。

したがって、の入力に対して15sixteen minus one15文字(スペースはカウントしません)を出力できます。複数のソリューションが存在する場合は、必要なものを印刷してください。存在しない場合は、印刷しますimpossible

唯一の演算子を使用してplusminustimes、とdivided by。演算子は左から右に評価されます。

1234をとしてフォーマットしone thousand two hundred thirty fourます。「and」がなく、ダッシュやコンマがないことに注意してください。

出力で使用される入力とすべての数値は、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.ゼロを除外することもできます。あなた次第。
レベルリバーセント

@steveverrill良い点; 「正の整数」に変更しました。
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 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"、最短のパディング文字列である同じ観測を行い、15の基本文字列のいずれかをパッドの繰り返しコピーに連結することで、27より大きいすべての数値を表現できるようにしたようです。

そうは言っても、使用する基本文字列のテーブルは異なり、私の解決策はビット調整と剰余演算子(%)に依存しています。また"multiplied by"、可能な操作として含まれています。そして当然、文字列がどのように構築されるかのメカニズムは、CとJavascriptの違いのために完全に異なります。

とにかく、それが私の最善の試みです。;)

@chiruに感謝します。@ chiruは、どの数字が達成可能かを議論することで、無駄な検索を防ぐことができました。


22

JS、1719/1694

理論

残念ながら、提供するルールセットは、数学的な観点からは賢明な決定ではない場合があります。実際、ルールのより小さなサブセットを使用して、指定された間隔内のすべての数値の解決策を見つけることができます

I = [1;  10000]

を除いて

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

解決策はありません。

ルールセットの削減

次のルールのサブセットを検討してください。

  • 演算子のみを使用しplusminusそしてtimes
  • あなたは、実装する必要はありませんの複数の発生plusminus、あなたの表情でを。
  • あなたは、実装する必要はありませんどちらdivisionoperator associativity(彼らのソリューションセットは、すでに最初のルールで覆われているもの)を。

これが機能する理由は、前に@Qwixで説明したように、退屈な答え、つまり正規表現で終わる表現を 許可するため( times one)+$です。これを許可すると、指定された間隔の各数値に解決策があります。

コメントのいずれかで返信すると、

@Qwixはい; つまらない答えは受け入れられますが、それは104、105、106、107、108、109、110、または111では機能しません。

あなたは絶対に正しかった:数字自体、one hundred four times one times one …または他の数字から始まる式を構築しようとしているとき、これは機能しません。

ただし、式が評価が指定された数値の1つに等しい式で始まる場合、運が悪いです。たとえば、それ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することを確認するには、このファイルを名前を付けて保存し、コマンドライン用のJavaScriptエンジンであるSpiderMonkeyがシステムにインストールされていることを確認します。

アルゴリズム

  • K正の整数のプロパティNを、文字と値を持つ数値の状態として定義しますN
  • さらにF、式のプロパティを、単語変換の状態が8kk∈withでの評価よりも1倍短いと定義します。F"fillable"の略" times one"で、結果の式がpropertyを取得できるように、式の単語変換を長さ8の式で埋めることができるかどうかを示します(つまり)N

次に、次の手順を実行します。

  • 入力番号を単語に変換します。
  • 入力番号にpropertyがあるかどうかを確認してくださいK
    • 存在する場合、単語を返します(4残念ながら、このプロパティを持つ唯一の数字です)。
    • そうでない場合は、続行します。
  • 入力数が得られるすべての2オペランド式(この順序での加算、減算、乗算)について、それらの評価にpropertyがあるかどうかを確認しますK
    • もしそうなら、単語を返します。
    • そうでない場合は、2つのオペランドの式にpropertyがあるかどうかを確認しますN
      • 含まれている場合は、" times one"式を入力して、結果の式の評価にpropertyがあるかどうかを確認します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:式内の部分文字列「times one」の出現回数(最小0、最大1245)

グラフ

結論:

  • 式は線形的に退屈になる傾向があります。
  • ソリューションの99%以上は退屈です。

2
4 exists-のためのソリューションfour
FUZxxl

@FUZxxl私はそれを決して否定しませんでした。に応答している場合If it does, return the words (4 is the only number with this property, unfortunately)、このセクションを誤解している可能性があります。それは、それ4が独自のソリューションを形成する唯一の演算子なしの式であると言います。
チル14

@FUZxxlああ、わかりました。最初のセクションで、X = [0;には解が存在しないと言いました。10]∪{12}、後でです4が、解決策があると言います。間隔を修正しました、ありがとう。:)
Chiru 14

6

C、450文字

編集:削除 zero

編集:とのみplusを使用minus

文字を追加して条件を真に保つ最短の式を検索しました。plus ten plus five長さが15で、文字列に15が追加されていることがわかりました。

可能な数字を表現するために、不可能ではない最初の15個の数字の表現だけが必要です。12は最大の不可能な数値であるため、28より小さい数値をハードコードするだけで十分です。

4 = 4
11 = 6 + 5
13 = 8 + 5
14 = 20マイナス6
15 = 20マイナス5
16 = 18マイナス2
17 = 14プラス3
18 = 22-4
20 = 32-12
21 = 20プラス2マイナス1
22 = 20プラス4マイナス2
23 = 30マイナス8プラス1
24 = 20 + 8-4
25 = 20プラス8マイナス3
27 = 28-6 + 5

27以上のすべての数値をx * 15 +上記の数値の1つとして書くことができます。

ゴルフ

#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
あなたのコードがどのように動作するのかはよくわかりませんが、質問にはが記載されているので、使用すべきではないのでZのインスタンスとともにコードからall numbers used in the output must be positive integers削除できます#define Z "zero"か?
Qwix 14

「プラス12」は12文字です。それはあなたのコードを短くするのに役立ちますか?
isaacg 14

私はそれを短くします、悲しいかなスペースplus twelveは数えません、たった10文字です
オプトコッパー14

OK、ルールを読み間違えました。
isaacg 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.