ランダムダイティッパーの検証


33

ほぼ6年前、仲間のPPCGメンバーsteenslag は次の課題を投稿しました。

標準のサイコロ(ダイス)では、反対側の面が7になるように番号が配置されます。ランダムスローに続いて9回のランダムチップを出力する、可能な言語で最短のプログラムを記述します。チップはサイコロの4分の1回転です。たとえば、サイコロが5に面している場合、すべての可能なチップは1,3,4および6です。

望ましい出力の例:

1532131356

だから、今では誰もがそれを完全に忘れており、勝者の答えは長い間受け入れられてきたので、提出されたソリューションによって生成されたダイチップシーケンスを検証するプログラムを書くことになります。(これは理にかなっています。そうするふりをしてください。)

チャレンジ

あなたのプログラムや関数は このようなシーケンスを与えています1532131356。連続する各桁が以下であることを検証します。

  • 前の数字と等しくない
  • 7から前の数字を引いものと等しくない

(最初の数字を検証する必要はありません。)

ルール

  • プログラムは、入力が有効な場合は真実の値を返し、そうでない場合は偽の値を返す必要があります。
  • 入力は1〜6の数字のみで構成され、少なくとも1文字の長さであると想定できます。シーケンスは、steenslagのチャレンジのように固定長になりません。
  • 入力は、文字列("324324")、配列または配列のようなデータ構造([1,3,5])、または複数の引数(yourFunction(1,2,4))として受け取ることができます。

標準のI / Oおよび抜け穴の規則が適用されます。

テストケース

真実の

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

偽り

  • 繰り返し数字

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • ダイの反対側

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    

回答:


14

パイソン2、43の 45バイト

lambda s:reduce(lambda p,n:n*(7-p!=n!=p>0),s)

43バイト(@Zgarbから大きな影響を受けています)

lambda s:reduce(lambda p,n:n*(p>0<n^p<7),s)

この関数は、reduceステートメントと@Zgarbの答えのビットフリックロジックを組み合わせて、両方より短い組み合わせにします。

両方の答えは次を出力します:

  • 入力が有効なシーケンスでない場合は0
  • シーケンスの最後の桁(有効な場合)

4
PPCGへようこそ、これは本当にいい最初の答えです。
小麦ウィザード

1
これは、偽のケースの約半分では機能しません。例えばを3132124225返します5
ジェイクコブ

を使用して修正できますn and p*(7-p!=n!=p)
ジェイクコブ

@JakeCobbこれで、すべてのテストケースで動作するようになります。残念ながら、現在は2バイト長くなっています:(
notjagan

reduceの巧妙な使用法。各値を次のステップに渡します。
XNOR

9

Python、44バイト

lambda x:all(0<a^b<7for a,b in zip(x,x[1:]))

ビット単位の魔法!これは、整数のリストを取得し、2つの連続する要素ごとのXORが1〜6の範囲にあることを確認する匿名関数です。

なぜ機能するのか

まず、7は1112を基数としているため、XORは常に0から7の範囲にあります。また、数字は最大3桁の2進数です。平等のために、次のa^b == 0場合にのみa == b。また、7-a == 7^awhen 0 ≤ a ≤ 7があり、したがってa^b == 7if ifのみですa == 7^b == 7-b


7

05AB1E 11 9バイト

-2バイトは、製品を使用するというOsableの賢明なアイデアです。

¥¹D7-Á+«P

オンラインでお試しください!

¥           # Push deltas.
 ¹D7-Á      # Push original array, and 7 - [Array] shifted right once.
      +     # Add original to the 7 - [Array] shifted right.
       «    # Concat both.
        P   # Product, if either contain a zero, results in 0, meaning false.

05AB1Eを使用する3番目のアプローチは、pairwiseコマンドを使用しません。

  • 0 ほろ酔い特性に違反する場合。
  • Not 0 それがほろ酔いであることを妨げるものがなかった場合。

1
@Emignaは、それが重要であるとは思わなかったが、修正された!
魔法のタコUr

1
デルタで回答を投稿したかったのですが、考えていませんでしたÁ。いいね!
2016

1
でtrue / falsy値の定義を使用して2バイトを保存できます¥¹D7-Á+«P。配列に0がある場合は0、それ以外の場合は他の値になります。
2016

1
@Osable SMAART!メガ賢者、良い仕事。
魔法のタコUr

6

R、39 37 32 31バイト

all(q<-diff(x<-scan()),2*x+q-7)

オンラインでお試しください!

stdinから入力を受け取ります。diff連続する2つの数字が同じかどうかを確認するために使用します。次に、各数字を7マイナス前の数字と比較します。返品TRUEまたはFALSE

Jarko Dubbeldamのおかげで5バイト、JayCeのおかげで5バイト節約できました。


いくつかの変数の違いを保存してqからテストする2*x+q-7代わりにc(0,x)!=c(7-x,0)、数バイトを節約します。もしx1 + x2 = 7、その後2*x1 + diff(x1,x2) = 7。チェックして2*x+q - 7から明示的にテストし!=0ます。
JAD

@JarkoDubbeldam素晴らしい観察、ありがとう!ソリューションを更新しました。
rturnbull 16


@JayCeありがとう、今すぐ答えを更新しました。
rturnbull

5

05AB1E、10バイト

$ü+7ʹüÊ*P

CP-1252エンコードを使用します。オンラインでお試しください!


1
ああ、なぜ私は考えなかったのかÊ:Pナイス!
エミグナ16

うーん、1*[] = []しかしproduct(1, []) = 1。知っておくといいです。
エミグナ16

@Emigna実際には、それはバグです。製品[]1でなければなりません
アドナン・

ええ、私はそれが数回前にそのように機能することを望んでいました。操作の順序もここで重要です。)1*)1s*)1Pされているすべての[]一方は)1sP1である
Emigna

1
@Emigna Ahh、それはの積が[]エラーを与えて破棄されるためです。それが1を与える理由です。私は家に帰ったら直そうとします。
アドナン

5

R、49 44バイト

!any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))

(スペースで区切られた)stdinから入力を読み取り、出力しますTRUE/FALSE。入力の長さが1であるが、それでも機能する場合は警告を出します。

編集:@rturnbullのおかげで数バイト節約


あなたは組み合わせることができall(x)&all(y)all(x,y)て、いくつかのバイトを節約ます。に切り替えrle(x)$l==1rle(x)$l-1、有効なFALSE場合にすべてのセットを返すこともできxます。その後切り替える!===allします!any。これにより!any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))、合計で5バイト節約されます。(PS、私はあなたが興味があるかもしれない代替ソリューションを書いた。)
rturnbull


4

JavaScript(ES6)、43 40バイト

0/を返しますtrue

f=([k,...a],n=0)=>!k||k-n&&7-k-n&&f(a,k)

テストケース


悲しいことに、Retinaアンサーの単純なポートはわずか38バイトです。
ニール

私はそれが実際にして37だと思う@Neiltest()
アルノー

申し訳ありませんが、バイトカウンターに誤って改行を貼り付けてしまいました。
ニール

4

Perl 6バイト

正規表現を使用する:

{!/(.)<{"$0|"~7-$0}>/}

入力を文字列として受け取ります。GBのRubyの回答に触発されました。
使い方:

  • / /:正規表現。
  • (.):任意の文字に一致し、次のようにキャプチャします $0
  • <{ }>:その位置で一致するサブ正規表現を動的に生成します。
  • "$0|" ~ (7 - $0):生成するサブ正規表現は、前の数字のみに一致するもの、または7から前の数字を引いたもの(例5|2)です。
    したがって、全体の正規表現は、無効な連続した数字のペアをどこでも見つけた場合に一致します。
  • {! }:ブール型に強制し(正規表現を照合させる$_)、それを否定し、全体をラムダに変換します(暗黙的なパラメーターを使用$_)。

Perl 6、38バイト

リスト処理の使用:

{all ([!=] 7-.[1],|$_ for .[1..*]Z$_)}

入力を整数の配列として受け取ります。
使い方:

  • .[1..*] Z $_:入力リストをそれ自体のオフセット1バージョンで圧縮し、2組の連続した数字のリストを生成します。
  • [!=] 7 - .[1], |$_:それらのそれぞれについて、を確認します(7 - b) != a != b
  • all ( ):すべてのループ反復がTrueを返したかどうかに応じて、真の値または偽の値を返します。

4

Python、38バイト

f=lambda h,*t:t==()or 7>h^t[0]>0<f(*t)

のような引数を取る再帰関数f(1,2,3)

これは、引数のアンパックを使用して、最初の数をhタプルに抽出し、残りをタプルに抽出しtます。tが空の場合、Trueを出力します。それ以外の場合は、Zgarbのビットトリックを使用して、最初の2つのダイスロールに互換性がないことを確認します。次に、末尾の再帰呼び出しでも結果が保持されることを確認します。


4

ルビー、34バイト

->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}

2
あなたは、文字列使用して、2つのバイト剃り落とすことができ#[]代わりの方法を:->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
アレクシス・アンデルセン

正規表現で使用できるとは知りませんでした、ありがとう。
GB

4

JavaScript 61 43バイト

コメントでは、usingステートメントを含めずにC#linq関数を使用することはできないと述べているため、標準JSを使用した場合のバイト数が少なくてもまったく同じです。

f=a=>a.reduce((i,j)=>i>6|i==j|i+j==7?9:j)<7

C#、99 67 65バイト

入力をint配列として受け取ります a

// new solution using linq
bool A(int[]a){return a.Aggregate((i,j)=>i>6|i==j|i+j==7?9:j)<7;}
// old solution using for loop
bool A(int[]a){for(int i=1;i<a.Length;)if(a[i]==a[i-1]|a[i-1]+a[i++]==7)return false;return true;}

説明:

// method that returns a boolean taking an integer array as a parameter
bool A(int[] a) 
{
    // aggregate loops over a collection, 
    // returning the output of the lambda 
    // as the first argument of the next iteration
    return a.Aggregate((i, j) => i > 6 // if the first arg (i) > than 6
    | i == j      // or i and j match
    | i + j == 7  // or i + j = 7
    ? 9   // return 9 as the output (and therefore the next i value)
    : j   // otherwise return j as the output (and therefore the next i value)
    ) 
    // if the output is ever set to 9 then it will be carried through to the end
    < 7; // return the output is less than 7 (not 9)
}

私は、このニーズは機能に包まれたことを考える、または多分ラムダ(C#がそれらを持っているのですか?)また、あなたが返すことによって、いくつかのバイトを救うことができる0か、1代わりのfalsetrue
DJMcMayhem

ああ、OK-コードゴルフの最初の投稿。編集します...
エレセン

問題ない。ところで、サイトへようこそ!:)
DJMcMayhem

@DJMcMayhem私が間違っていても修正しますが、出力要件が真実/偽であるため、出力オプションは言語依存ですtl; dr 1/0はc#で真実/偽ではありません-JustinM
Reinstate Monica

@Phaezeそれらは真実/偽ではないことは正しいですが、標準のIOルールmeta.codegolf.stackexchange.com/questions/2447/…は終了コードを使用して出力でき、その関数はプログラム。必要であれば、私は真偽値に戻って変更しますが、それは私にいくつか刺されのコストよ
Erresen

3

> <>(魚)47バイト

0:i:1+?!v\!
   0n;n1< >
!?-{:-"0"/^
!? -{-$7:/^

ものすごく単純;

1行目:数字が入力されているかどうかを確認します。数字がない場合(EOF)は、elseチェックを印刷する必要があります。

2行目:結果を出力します。

3行目:入力を数値(ASCII 0-入力から)に変換し、前の入力と等しいかどうかを確認します。

行4:入力がダイの反対側にあるかどうかを確認します。


3

Brain-Flak 128バイト

(()){{}(({}<>)<>[({})])}{}([]){{{}}<>}{}([]){{}({}({})<>)<>([][()])}{}(<{}>)<>(([])){{}{}({}[(()()()){}()]){<>}<>([][()])}({}{})

偽の場合は0、真実の場合は-7を出力します。

オンラインでお試しください!(真実)
オンラインで試してみてください!(フレージー)

説明(tは上を、sは上から2番目を意味します):

(())                # push a 1 to get this loop started
{{}                 # loop through all pairs, or until 2 are equal
(({}<>)<>[({})])    # pop t, push t on the other stack, and t - s on this one
}{}                 # end loop and pop one more time
([])                # push the height of the stack
{                   # if the height isn't 0 (there were equal numbers)...
{{}}<>              # pop everything from this stack and switch
}                   # end if
{{}                 # for every pair on the stack: pop the height and...
({}({})<>)<>        # push t + s on the other stack leaving s on this one
([][()])            # push the height - 1
}                   # end loop when there is only 1 number left
{}(<{}>)<>          # pop t, pop s, push 0 and switch stacks
(([]))              # push the height twice
{                   # loop through every pair
{}{}                # pop the height and what was t - 7
({}[(()()()){}()])  # push t - 7
{<>}<>              # if t is not 0 switch stacks and come come back
                    # if t is 0 (ie, there was a pair that added to 7) just switch once
([][()])            # push height - 1
}                   # end loop
({}{})              # push t + s (either 0 + 0 or 0 + -7)


3

PHP、63バイト

for($d=$argv[$i=1];$c=$argv[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);

コマンド引数のリストとして入力を受け取ります。1入力が無効な場合は(エラー0)、有効な場合は(ok)で終了します。

で実行 -nrます。

文字列引数として入力、65バイト

for($d=($s=$argv[1])[0];$c=$s[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);

3

PowerShell57 44 41バイト

取り消し線44はまだ通常の44です

0-notin($args|%{7-$_-$l-and$l-ne($l=$_)})

オンラインでお試しください!

(OPは、入力を個別の引数として使用しても問題ないことを明確にしました-13バイトを節約しました... $b

$args一度に1桁ずつ入力をループしています。各桁は、我々がいることを確認し$l、AST桁である-nOT e現在の桁にQUAL $_、かつ、7-$_-$l(truthyある)がゼロ以外の数です。これらのブール結果は括弧でカプセル化され、演算子の右側のオペランドに入力され、-notinに対してチェックされ0ます。言い換えれば、もしあればFalse、ループ内のどこ値、-notinにもなりますFalse。そのブール値はパイプラインに残り、出力は暗黙的です。

$変数名が必要なため、また-ne -and、PowerShellではブール型のコマンドが冗長であるため、時間がかかります。しかたがない。


3

処理、93 92 90バイト

変更 || | @ClaytonRamseyに1バイトの保存ありがとう:

後方カウントを開始:@IsmaelMiguelのおかげで2バイト節約

int b(int[]s){for(int i=s.length;--i>0;)if(s[i-1]==s[i]|s[i-1]==7-s[i])return 0;return 1;}

入力をintの配列、出力として受け取ります 1をtrueまたは0falseにします。

非ゴルフ

int Q104044(int[]s){
  for(int i=s.length;--i>0;)
    if(s[i-1]==s[i]|s[i-1]==7-s[i])
      return 0;
  return 1;
}

通常、Javaでは ||の代わりに バイトを保存したい場合。
クレイトンラムジー

@ClaytonRamseyなぜ私はそれを考えなかったのか分からない、ありがとう!
Kritixi Lithos

私は別のものを見つけました。三次演算子
クレイトンラムジー

@ClaytonRamsey return 0はif文の中return 1にありますが、そうではありません。他のアイデアがない限り、それがどのように可能かはわかりません
Kritixi Lithos

2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<-持っているものと持っているものを比較しながら読みました。
イスマエル・ミゲル

3

C 47 44バイト

F(char*s){return!s[1]||(*s^s[1])%7&&F(s+1);}

数字のストリング(またはゼロで終わるバイトの配列)を取ります

説明

F(char*s){

標準のint戻り値の型に応じて暗示されます。(4バイトを節約)

return これは再帰関数であるため、無条件に戻ります

ショートカット評価の使用:

!s[1]||2番目の文字がnulの場合、trueを返します

((*s^s[1])%7&& 最初の2文字が法律上の偽ではない場合

F(s+1)) 同じ方法で文字列の残りを確認してください

その紛らわしい表現

*s最初の文字s[1]は2番目です

*s^s[1] それらが同じ場合、それらを排他的論理和します。7に加算すると結果は0になります(7に加算して7に加算しない場合、結果は1〜6になります)

したがって(*s^s[1])%7、不正な入力の場合はゼロ、それ以外の場合は非ゼロです。したがって、これらの2文字が不正な場合はfalse、そうでない場合はtrueです。

コメント: この関数呼び出しは最後の再帰のみを使用するため(最後のステートメントのみが再帰呼び出しです)、オプティマイザーは再帰をループに変換できます。これは幸福な一致であり、明らかにゴルフスコアの価値はありませんが、スタックを使い果たすことなく、任意の長さの文字列を処理できます。


1
あなたについて!((*s^s[1])%7)私はあなたが欲しくないと思います!。不正な入力のゼロ値は偽物になるため、不正な場合は偽物を返します。
nmjcman101 16

2

Python、71バイト

f=lambda s:len(s)<2or(s[0]!=s[1]and int(s[0])!=7-int(s[1]))and f(s[1:])

再帰的アプローチを使用します。

説明:

f=lambda s:                                                              # Define a function which takes an argument, s
           len(s)<2 or                                                   # Return True if s is just one character
                      (s[0]!=s[1]                                        # If the first two characters matches or...
                                 and int(s[0])!=7-int(s[1])              # the first character is 7 - the next character, then return False
                                                           )and f(s[1:]) # Else, recurse with s without the first character

入力はintのリストであり、キャストは必要ないと言います。
Jasen


2

MATL、9バイト

dG2YCs7-h

入力は、数字を表す数字の配列です。

出力は空ではない配列であり、すべてのエントリがゼロ以外の場合は真実であり、そうでない場合は偽です(真実および偽のMATLの基準についてはこちらを参照してください))。

オンラインでお試しください!または、すべてのテストケースを確認します

説明

d     % Take input implicitly. Consecutive differences
G     % Push input again
2YC   % Overlapping blocks of length 2, arranged as columns of a matrix
s     % Sum of each column
7-    % Subtract 7, element-wise
h     % Concatenate horizontally. Implicitly display

新しいMATLAB関数をMATLに追加することは可能ですか?
rahnema1

@ rahnema1はい、現在使用されていない関数名がいくつかあります。ただし、私は選択的である傾向があり、頻繁に使用されると思われるもののみを追加します。あなたはどんな提案を持っている場合は、私たちはそれらを議論することができMATLチャットルーム :-)
ルイスMendo

@ rahnema1について考えているのであればmovsum、すでにconv2(を含むconv)があります。見るY+Z+
ルイス・Mendo

2

C#(Linqを使用)90 81 73 71 69 68バイト

using System.Linq;n=>n.Aggregate((p,c)=>p<9|c==p|c==103-p?'\b':c)>9;

説明:

using System.Linq;           //Obligatory import
n=>n.Aggregate((p,c)=>       //p serves as both previous character in chain and error flag
    p<9                      //8 is the error flag, if true input is already invalid            
        |c==p            
            |c==103-p        //103 comes from 55(7) + 48(0)
                ?'\b'       //'\b' because it has a single digit code (8)
                    :c)      //valid so set previous character, this catches the first digit case as well
                        >8;  //as long as the output char is not a backspace input is valid

2

C、81バイトは85バイトでした

int F(int *A,int L){int s=1;while(--L)s&=A[L]!=A[L-1]&A[L]!=(7-A[L-1]);return s;}

入力は、長さLの整数Aの配列です。trueの場合は1、falseの場合は0を返します。入力は、長さLを配列インデックスとして使用して、最後から最初までチェックされます。


int is optional at the start, you can save 4 bytes.
Jasen

int s=1; can be declared outside the function as s=1; for another 4.
nmjcman101

2

Haskell, 37 bytes

f(a:b:c)=a+b/=7&&a/=b&&f(b:c)
f _=1<2

Usage example: f [1,5,2] -> False.

Simple recursion. Base case: single element list, which returns True. Recursive case: let a and b be the first two elements of the input list and c the rest. All of the following conditions must hold: a+b/=7, a/=b and the recursive call with a dropped.


2

JavaScript, 40 bytes

f=i=>i.reduce((a,b)=>a&&a-b&&a+b-7&&b,9)

Takes advantage of the JavaScript feature that && will return the last value that is parsed (either the falsy term or the last term). 0 is passed along if it doesn't meet the conditions, and the previous term is passed along otherwise. The 9 makes sure that it starts with a truthy value.



1

Python 2, 58 Bytes

lambda x:all(x[i]!=x[i+1]!=7-x[i]for i in range(len(x)-1))


1

Batch, 102 bytes

@set s=%1
@set/an=0%s:~0,2%,r=n%%9*(n%%7)
@if %r%==0 exit/b
@if %n% gtr 6 %0 %s:~1%
@echo 1

Ungolfed:

@echo off
rem grab the input string
set s=%1
:loop
rem convert the first two digits as octal
set /a n = 0%s:~0,2%
rem check for divisibility by 9 (011...066)
set /a r = n %% 9
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem check for divisibility by 7 (016...061)
set /a r = n %% 7
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem remove first digit
set s=%s:~1%
rem loop back if there were at least two digits
if %n% gtr 6 goto loop
rem truthy output
echo 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.