コードを組み合わせロックにクラックする


22

写真のような標準の組み合わせロックを考えてみましょう。ロックを解除する方法は、組み合わせ行のコードの4つの数字を揃えることです。長年の忠実なサービスの後、あなたはロック工場から解雇され、ロックを送り出す前にジャムをしないことで正確な復geを決定しました。

コンビネーションロック

また、他の行の数字の順序を確認することで、組み合わせ行にある数字を決定することができることを知っています(したがって、ロックを解除する組み合わせがあります)。

ロックのすべての行に、組み合わせ行(ロックを解除する行)の行0から行9までの番号が与えられている場合。たとえば、行4の番号がの場合、5336ロックを解除する組み合わせはになります1992

残念ながら、ロックはすでにパッケージ化されており、各ロックの表示が不明瞭になっているため、ロックの異なる行の数字しか見ることができません。

チャレンジ

整数の最初の桁が行番号を表し、2番目の桁がその行に表示される番号を表す4桁の数字が与えられたら、ロックへの組み合わせを計算します。たとえば、次を入力した場合:

57 23 99 45

次に、出力する必要があります:

2101

または

25 78 63 15

そして

3174

入力は常に `25 64 72 18の形式の4つの正の整数であると仮定します。

これはであるため、バイト数の最も短いプログラムが優先されます。

また、これは私の最初の質問ですので、フィードバックを歓迎します。


入力を明確にする必要があると思います。あなたは " 整数の4つのペアが与えられた "と言って、次に例を与え57 23 99 45ます。それは4つの整数のペアではありません。4つの整数です。そして、いくつかの答えは、それを文字列として取得することを前提としていますが、他の答えは、4つの整数としてすぐに解析されると想定しています。
ピーターテイラー

私は、それは57行が57だったとの組み合わせが23だったこと57.私の最初の仮定がした整数整数対5と7、ではない、整数の4ペアが、入力のフォーマットが明らかにされたという事実を反対します
Qwerty01

1
「数字のペア」はどうですか?それははるかに明確で正確です(また、主要な0s でも動作します)。
ふわふわ14

技術的には、正しい用語は置換ロックです。ほとんどの「組み合わせロック」は、実際には順列ロックです。これは、数字の順序によって違いが生じるためです。
nyuszika7h 14

技術的には正しいのですが、キャッチーなタイトルになるとは思いません。
ロリーマクパーロイ14

回答:


32

CJam、9 8バイト

ea9fbAf%

数字のペアをコマンドライン引数として読み取ります。するには、オンラインでのコードを試してみてください、変更をeaするためにlS/シミュレートさSTDINからの読み取りに。

実行例

$ cjam <(echo ea9fbAf%) 57 23 99 45; echo
2101
$ cjam <(echo ea9fbAf%) 25 78 63 15; echo
3174

使い方

数字dの文字コードは48 + dです。したがって、2桁の文字列xyを考えると、基数9の数値は9 *(48 + x)+(48 + y)= 10 *(48 + x)+ y-x≡y-x(mod 10)になります。

ea       " Push the array of command-line arguments.                                      ";
  9fb    " Mapped base 9 conversion; replace each string 'xy' with (9 * ord(x) + ord(y)). ";
     Af% " Take the results modulo 10.                                                    ";

くそー、他の誰かに勝つことはできませんよね?:P
オプティマイザー

これよりも良いCJamの回答が得られるとは思わない
ロリーマクパーロイ14

1
そこで何が起こったのですか?
戦争

1
@DigitalTrauma:もちろん、どうぞ。文字列"99"は実際には配列として解釈さ[57 57]bます; "xy"9bとして実装され9 * ord(x) + ord(y)ます。それを答えに追加する必要があります。
デニス14

4
可能なソリューションを印刷可能なASCIIに制限する場合、 10,000はすべての2文字プログラムをほとんどカバーしません。
デニス14

13

CJam、13 12 11文字

user23013のおかげで、11文字になりました:)

4{Ar:--A%}*

説明:

4{       }*     "Run the code block 4 times";
   r            "Read the next input token (whitespace separated)";
    :-          "Subtract 2nd number from the first treating r as a 2 numbered string";
  A   -         "Subtract the result of above from 10";
       A%       "Take modulus of 10 and store it on stack";

オンラインで試す

もっとゴルフができることを知っています。しかし、これはCJamでの私の最初の実際の試みであり、経験によって制限されています:)


あるいは、1つの追加文字で同じことを行う他の方法:

l~]{_A/-A%}/     // My previous solution

または

4{ri_A/-A%}*     // As pointed out by Ingo

または

ea{i_A/-A%}/     // If input is passed through command line

これを待っていました。さて、来週...
Soham Chowdhury

あるいは、最初の3文字はである可能性がありますl~]。私は3未満で可能でなければなりません入力を解析するように感じるが、私は前にCJamを使用したことがありません:/
インゴ・バーク

4{ri_A/-A%}*1バイト短くなります。
インゴバーク

1
ああ、またはあなたが私の以前のコメントから作ったもの。さて、2つの12バイトソリューションがあります!:)
IngoBürk14年

3
または4{Ar:--A%}*
jimmy23013

6

Golfscript(14 13

こちらからオンラインでお試しください

オプティマイザーのソリューションとほとんど同じですが、言語が異なります。問題はかなり単純なので、別の方法でアプローチすることは困難です。そのため、タイは間違いなくオプティマイザーに行きます。

~]{.10:^/-^%}/

同じバイト数でできること

~]{.10/- 10%}/

Golfscriptに値10の定義済み変数はありませんか?
オプティマイザー

@Optimizer残念ながら、ありません。スタックに入力があることは、CJamよりも有利だからです。
インゴバーク

ええ、CJamでは10文字(スタックへの入力あり)、Golfscriptでは11文字(定義済みの変数あり)
オプティマイザー

スペースを残す必要がなければ、Golfscriptに12も持つことができました- 10
インゴバーク

1
あわや、でも言語の最短は、彼らの持っている短い欠点を:P
オプティマイザ

6

GNU dc、14バイト

@Dennis の賢いベース9トリックを借りる:

9i[?A%nd]dxxxx

STDINから読み取られた入力整数。1行に1つ。

説明:

9i                # Set input radix to 9
  [     ]         # push a macro, defined thus:
   ?              #   read number from STDIN and push
    A             #   push literal 10
     %            #   calculate number mod 10
      n           #   print, with no newline
       d          #   duplicate macro
         d        # duplicate macro
          xxxx    # execute the macro 4 times    

出力:

$ for i in 57 23 99 45; do echo $i; done | dc ./combolock.dc
2101$ 
$ for i in 25 78 63 15; do echo $i; done | dc ./combolock.dc
3174$ 
$ 

前の回答、18バイト:

私はこれで「ゴルフ」言語に近づくことができると思っていたので(そうしなかった):

[A?A~--A%n]dddxxxx

1
あなたはバイトを保存することができます:9i[?A%nd]dxxxx
デニス

@デニス-ファンタスティック!今、私はgolfscriptとAPLで首と首です!
デジタル外傷14

6

C 64 63 56または61

入力をファイルからパイプできる場合

main(a){while(scanf("%d",&a)>0)putchar(48+(a-a/10)%10);}

入力を標準入力に入力する必要がある場合

i;main(a){for(;i++-4;putchar(48+(a-a/10)%10))scanf("%d",&a);}

ループ内の4つの数値を読み取り、値から最初の数字を減算して結果を10を法として出力することにより、それぞれを処理します。

以下のさまざまなコメントと、printfの代わりにputcharを使用したことによる節約


クール。あなたは置くことによって、コンマを保存することができますscanf外にfor()このようなa,i;main(){for(;i++-4;printf("%d",(a-a/10)%10))scanf("%d",&a);}
レベル川セント

あなたは可能性も使って、2バイトの保存a*.9の代わりにa-a/10
REV

@steveverrillそれが好きです。だから私はそれを逃したことをループのためにすべてを置くことに焦点を当て
アルキミスト

1
@AcidShout申し訳ありません-それは動作しません。たとえば、78 * .9 = 70.2、78-78/10 =71。また、.9を使用すると、引数がdoubleに昇格するため、modを使用できません。
アルキミスト

あなたは、使用して数バイトを救うことができるwhileループをし、宣言aの引数としてmainmain(a){while(scanf("%d",&a)>0)printf("%d",(a-a/10)%10);}
デニス

5

Python 3、64

簡単です。

print(''.join([(i-i//10)%10 for i in map(int,input().split())]))

たとえば、[2, 1, 0, 1]代わりに(46)印刷することが許可されている場合は、短くすることができます:

print([i%10-i//10 for i in map(int,input().split())])

str((i-i//10)%10)2番目のを使用する代わりに直接取得することで、いくつかを保存できますmap()。私も私のジェネレーターで始めましたが、実際のforループは短くなっていることがわかりました。
DLosc

うん、ありがとう!
ソハムチョードリー14

なぜリスト内包表記を使用しているのですか?genexpsを使用して、2文字を保存しますprint(''.join((i-i//10)%10for i in map(int,input().split())))。また、出力でスペースが許可されている場合は、joinタプルのアンパックを回避して使用できますprint(*((i-i//10)%10for i in map(int,input().split())))
バクリウ14

あなたは正しいと思います。
ソハムチョードリー14

4

C、92

#define a(n) ,(10+v[n][1]-*v[n])%10
main(int c,char**v){printf("%d%d%d%d"a(1)a(2)a(3)a(4));}

コマンドラインからの入力。各引数の最初のASCIIコードを2番目の引数から減算し、10を加算して10を法とします。

コンマなしprintfで4つ%のsを記述したのはこれが初めてだと思います(コンマはにあります #define.


#define f scanf("%c%c ",&a,&b);putchar(48+(9*a+b)%10)続いてa,b;main(){f;f;f;f;}18バイト短くなります。
デニス14

@Dennisは大きな改善ですが、基本的にはまったく異なるプログラムです。誰かがそれを投稿したら、それは私ではなくあなたであるべきだと思います。空白がセパレータとしてのみ解析されることになっているので、スペースscanfが必要かどうかはわかりませんscanf。AlchymistはCでさらに優れたアイデアを持っています。しかし、Cjamの回答ですでに勝ち取っているようです。
レベルリバーセント14

ええ、私はスペースの後ということに気付いによって開始a(n)省略することができ、その後、私は入れていることに気づいたprintf("%d%,...)あなたのマクロの周りには数バイトを救うし、最終的に私が...少しは夢中になっ-ので、スペースが必要とされている%c文字を読み込み、任意の文字なので、2回目の実行では32を格納しaます。-CJamをCで破るのは難しいはずです。printf()...私の答え限り、既にある
デニス・

4

Java-203バイト

そこからといっていたJavaエントリであることを、私はチャンス(初投稿)をゴルフこのコードを与えるために素敵な機会を見ました。

class M{public static void main(String[] a){String r="";for(int i=0;i<4;i++){int l=Byte.valueOf(a[i].substring(1));int f=Byte.valueOf(a[i].substring(0,1));r+=(l-f<0)?l-f+10:l-f;}System.out.print(r);}}

改善の余地があるなら、私はそれらについて知ってうれしいです;-)


[ヒント]を検索して、ゴルフに関するさまざまなヒントを入手して開始できます:)
オプティマイザー

クール、ありがとう!いくつかのヒントを確認すると、13バイトを削ることができました:)
サンダー14

3

ルア-46文字

while''do a,b=io.read(1,1,1)print((b-a)%10)end

一度に3文字を読みます(最後にスペースを入力するという小さな慈悲を与えてくれます)。aとbは文字列ですが... ba MAGICALUALYは健康な赤ちゃんの整数を想像できます。印刷中に折り返しチェックを行います。

実行方法:


1
あなたはそれが上で実行するように見えることはできません、例えば、データ入力/出力を提供することができIdeone
ロリーMcPerlroy

@ Harry12345あ、ごめんなさい。Anarchy Golfは、stdinputの実装方法に心を決めています。私はおそらくそれをより良くコーディングできましたが、まあ、luaはひどいです。プログラムを実行している私の例を投稿しました。
AndoDaan

3

JavaScript ES6 – 53 43バイト

f=n=>n.replace(/.. ?/g,a=>(1+a[1]-a[0])%10)

かなり簡単な関数で、正規表現を使用して数値を取得します。http://jsfiddle.net/efc93986/1/で試してください。関数が許可されていない場合、52バイトのスタンドアロンプ​​ログラム:

alert(prompt().replace(/.. ?/g,a=>(1+a[1]-a[0])%10))

現在ES6はFirefoxでのみ動作するため、次のコードは最新のブラウザーで70バイトで動作します。

alert(prompt().replace(/.. ?/g,function(a){return(1+a[1]-a[0])%10}))

私はあなたを愛しています1+
ニール

1
質問では、有効な入力を想定しているため、の...?代わりに使用できます/\d+ ?。復帰後のスペースは省略できます。また、特定のI / Oが指定されていないため、関数を使用できるはずです。
デニス14

1
a-a[0]代わりに1+a[1]-a[0]同様に動作するはずです。
デニス14

2

Python 2-33バイト

for i in input():print(i-i/10)%10

コンマ区切りのユーザー入力を受け入れます。例:入力:

29,26, 31, 88

出力:

7
4
8
0

出力が例と正確に一致する必要がある場合、それははるかに長くなります。47バイト:

print"%d"*4%tuple((i-i/10)%10 for i in input())

input()私のPython 2インタープリターでは動作しません。
ソーハムチョードリー

@SohamChowdhuryはコンマを使用しましたか?
feersum

2
ああ、いや、そうしなかった。今は動作します。サイドノートでは、私は考えてあなたが仕様ごとのスペース区切りの入力を取る必要があります。
ソーハムチョードリー

3
入力はスペースで
区切る

2

APL、14

10|{--/⍎¨⍕⍵}¨⎕

説明
は画面から入力します。スペースで区切られた値は、配列として解析されます。
{...}¨各番号について、関数に送ります。
⍎¨⍕⍵引数を取り、その数字の配列を作成します。
--/10を引いた単位を計算します。
10|mod 10。


1
これは14文字かもしれませんが、24 バイトです。
インゴバーク

@IngoBürkcodegolf.stackexchange.com/ questions
TwiNight

しかし、コードゴルフでは、特別な文字セットではなくUTF-8でカウントします。これは単なる抜け穴であり、非常に簡単に悪用される可能性があります。
インゴバーク

1
@IngoBürkmeta.codegolf.stackexchange.com/ a / 961 / 6972によると、OPで特に明記されていない限り、回答は任意のエンコードでエンコードできます。実際、シングルバイトマッピングであるAPL文字用のIBMコードページがあります。これは、DyalogがUnicode 3.0以前に使用していたものです。ユニコードを主張している場合、非ユニコード文字を使用する新しい言語を発明したらどうでしょうか?そのためにどのようにバイトをカウントしますか?
TwiNight

デフォルトはUTF-8であると断言できました。それでは、14バイトです。
インゴバーク14

2

J- 20 15

動詞以外の形式(関数定義ではなくステートメントとして)は、5文字短くなります。

10|-~/|:10#.inv

素敵な列車である動詞形式:

10|[:-~/[:|:10#.inv]

入力例で使用されるこの動詞:

   10|-~/|:10#.inv 57 23 99 45
2 1 0 1
   10|-~/|:10#.inv 25 78 63 15
3 1 7 4

rotd =: 10|[:-~/[:|:10#.inv] NB. verb form

   rotd 25 78 63 15
3 1 7 4
   rotd 57 23 99 45
2 1 0 1

2

ハスケル60 58

main=interact$show.map((\x->mod(x-x`div`10)10).read).words

Haskellゴルフの本当の宿敵である1文字の数字。


2

Perl:38 40

print abs($_-int$_/10)%10for split" ",<>

出力:

% perl code.pl
57 23 99 45
2101

25 78 63 15                                     
3174

1
1.アンダースコアはマークダウン構文であるため、コードが少し混乱しました。これを防ぐには、コードを4つのスペースでインデントします。2. abs必要ありません。x - x/10負にはできません。3.フラグ-040pe(通常は5バイトとしてカウントされます)を使用してスペース区切りの入力を反復処理する場合、コードをに短縮できます$_=($_-int$_/10)%10。4.コマンドラインフラグを回避したい場合は$/=$;、への呼び出しを設定および削除することで、数バイトを節約できますsplit
デニス14

1

ルビー、35バイト

$*.map{|n|a,b=n.bytes;$><<(b-a)%10}

説明

入力はコマンドライン引数として取得されます。String#bytes整数の配列(ASCII文字コード)を返します。重要なのは最後の文字コードと最初の文字コードの違いだけであり、整数自体は重要ではありません。


1

C#およびLinqPad:104

Util.ReadLine<string>("").Split(' ').Select(s =>(s[1]-s[0])).Aggregate("",(r,a)=>r+(a<0?10+a:a)).Dump();

1

C ++ 118

int main()
{
int a,b,c;
for(int i=0; i<4; i++)
{
cin>>a;
b=a/10;
a=a%10;
c=a-b;
if(c<0)c+=10;
cout<<c;
}
}

他のコンパイラについて1。わからないが、GCCは必要です#include<iostream>し、std::cincout。2.を省略しa=a%10た場合、条件は必要ありません。3.変数bc、ラインフィード、およびforループの周りの(いくつかの変更を加えた)括弧は必要ありません。
デニス14

1
@SeanD:コードを変更する編集を承認しないでください。この特定のケースでは、編集により回答が無効になりました。また、すべての回答にあるはずの最初の行も削除しました。
デニス14

1
(CC @TeunPronk)
デニス

通常、このサイトの@Dennisの回答には、プリプロセッサの行は含まれていません。私はラインを省略#include<iostream>してusing namespace std;
bacchusbeale

通常、バイトカウントに含まれていないことは知っていますが、答えに含まれているはずです。
デニス14

1

PHP-90文字

私はコードゴルフを試してみたいと思ったので、ここでそれが私の最初の試みです-おそらくもっとゴルフができるでしょう。

<?php $a=array(57,23,99,45);foreach($a as$b){echo abs(substr($b,0,1)-substr($b,1,1)%10);}

58文字(イスマエルミゲル提供)

for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);

を使用してファイルにアクセスする

file.php?n=57239945

次のコードを試してください:<? for($i=0;$i<4;)echo abs($_GET[n][$i]%10);44文字です。を使用してブラウザからアクセスしfile.php?n[]=xx&n[]=yy&n[]=xy&n[]=yxます。(テストされていないコード)
イスマエルミゲル14

使用$_GETすることをお勧めしますが、57%10と表示され、(5-7)%10が必要です
ロリーマクパーロイ14

これを試してください:<? for($i=0,$a=$_GET[n];$i<4;++$i)echo abs($a[$i][0]-$a[$i++][1]%10);。残念ながら、長さは65バイトです。($i最後の増分を忘れてしまった)または、61バイトの長さで<? for($i=0;$i<8;)echo abs($_GET[n][$i++]-$_GET[n][$i++]%10);ブラウザを使用してアクセスすることもできfile.php?n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=y&n[]=x&n[]=yます。
イスマエルミゲル

ええ、2番目のものは動作します$_GET['n']。私の答えを編集しました。
ロリーマクパーロイ14

まあ、それは必須ではありません。単に警告を発行するだけです。これはこのWebサイトに適しています。しかし、これを試してください:<? for($i=0,$a=$_GET[n];$i<8;)echo abs($a[$i++]-$a[$i++]);%10無用であり、この1は単純に良く見えます。また、を使用してアクセスできますfile.php?n[]=xyxyxyxy。このソリューションの長さは58バイトです。
イスマエルミゲル

0

Python 3、60

for x in input().split():print(-eval('-'.join(x))%10,end='')

指定されたとおりに入出力しますが、末尾の改行は出力しません。ここでの2つの興味深いトリック:1)への2つの呼び出しをint()1 つの呼び出しに置き換えeval()、2)join()get を使用してa-bb-a必要に応じて無効にします。幸いなことに、Pythonのモジュロ演算子は、最初の引数が負であっても正の値を返します!


なぜこれがダウン投票されたのですか?完璧に機能します。(ところで、eval('-'.join(x))トリックは素晴らしいです。)
flornquake 14

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