バーコードは有効ですか?


33

EAN-8バーコードは7情報の桁と8チェックサム・デジットを有しています。

チェックサムは、数字に3と1を交互に掛け、結果を加算し、次の10の倍数から減算することで計算されます。

たとえば、数字が与えられた場合2103498

Digit:        2   1   0   3   4   9   8
Multiplier:   3   1   3   1   3   1   3
Result:       6   1   0   3  12   9  24

これらの結果の数字の合計は55なので、チェックサムの数字は60-55 = 5です。


チャレンジ

あなたの仕事は、8桁のバーコードが与えられたら、それが有効かどうかを確認することです。チェックサムが有効であれば真理値を返し、そうでなければ偽りを返します。

  • 次のいずれかの形式で入力できます。
    • バーコードの数字を表す8文字の文字列
    • 8つの整数のリスト、バーコードの桁
    • 非負の整数(1= が指定されていない場合、先行ゼロを想定するか00000001、ゼロが指定された入力を要求できます)
  • EAN-8チェックサムを計算する(つまり、最初の7桁を取得して最後の桁を計算する)ビルトインは禁止されています。
  • これはなので、最短のプログラム(バイト単位)が勝ちです!

テストケース

20378240 -> True
33765129 -> True
77234575 -> True
00000000 -> True

21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False


1
この質問は、実際にはバーコード(白黒の縞模様のもの)ではなく、バーコードによってエンコードされた番号に関するものです。番号はバーコードなしで存在でき、バーコードはEAN以外のものをエンコードできます。たぶん、「私のEAN-8が有効か」という方が良いタイトルでしょうか?
パエロエベルマン

2
@PaŭloEbermannは同じリングを持っていません
...-FlipTack

7
バーコードについて読むとき、チェックサムを検証しないで、いくつかの画像読み取り(または少なくともビット文字列)を期待します。
パエロエベルマン

ISBN-13はEANであるため、強く関連しています。
オリヴィエグレゴワール

回答:


5

ゼリー、7バイト

s2Sḅ3⁵ḍ

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

使い方

s2Sḅ3⁵ḍ  Main link. Argument: [a,b,c,d,e,f,g,h] (digit array)

s2       Split into chunks of length 2, yielding [[a,b], [c,d], [e,f], [g,h]].
  S      Take the sum of the pairs, yielding [a+c+e+g, b+d+f+h].
   ḅ3    Convert from ternary to integer, yielding 3(a+c+e+g) + (b+d+f+h).
     ⁵ḍ  Test if the result is divisible by 10.

13

JavaScript(ES6)、41 40 38バイト

@ETHProductionsのおかげで2バイト、@ Craig Ayreのおかげで1バイト節約されました。

s=>s.map(e=>t+=e*(i^=2),t=i=1)|t%10==1

入力を数字のリストとして受け取ります。

チェックサムを含むすべての数字の合計を決定します。

合計が10の倍数である場合、それは有効なバーコードです。

テストケース


私はあなたがで3つのバイトを救うことができると言うつもりだった再帰を投稿する前再帰からの切り替えg=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1...、しかし、あなたはより良い方法を発見したかもしれない
ETHproductions

ありがとう、@ ETHproductions、私はに変更しました。map入力は文字列ではなく数字のリストにできるので、これはうまくいくと思います。
リックヒッチコック

おそらく別のバイトを保存するにはs=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1
ETHproductions

はい、素晴らしい、ありがとう:)
リックヒッチコック

素晴らしい解決策!true / falsyが許可されているため、1/0を出力に置き換え&&|もらえますか?
クレイグ・アイレ


8

ゼリー、8バイト

m2Ḥ+µS⁵ḍ

テストスイートを試してください。

ゼリー、9 バイト

JḂḤ‘×µS⁵ḍ

オンラインで試す、テストスイートを試します。

仕組み

m2Ḥ+ µS⁵ḍ〜完全なプログラム。

m2〜Modular2。入力の2番目の要素ごとに返します。
  Ḥ〜それぞれ2倍。
   + µ〜入力を追加し、新しいモナドチェーンを開始します。
     S〜合計。
      ⁵ḍ〜10で割り切れますか?
JḂḤ '×µS⁵ḍ〜フルプログラム(モナド)。

J〜1インデックス付きの長さの範囲。
 Ḃ〜ビット; 上記の範囲の各数値を2でモジュロします。
  Ḥ〜それぞれ2倍。
   '〜増分します。
    ×〜入力とのペアワイズ乗算。
     µ〜新しいモナド連鎖を開始します。
      S〜合計。
       ⁵ḍ〜合計は10で割り切れますか?

バーコードの最初の7桁とチェックサム桁の結果は、有効になるために10の倍数に加算する必要があります。したがって、チェックサムは、リスト全体に適用されるアルゴリズムが10で割り切れる場合にのみ有効です。


まだ9バイトですが、値は一貫しています:JḂḤ‘×µS⁵ḍ
-HyperNeutrino

@HyperNeutrinoありがとう、これには原子があると知っていた!
ミスターXcoder

また9バイト::JḂaḤ+µS⁵ḍP
HyperNeutrino

まあ@HyperNeutrinoがあり、多くの選択肢のは:P
ミスターXcoder

1
8バイトまたは8文字?m2Ḥ+µS⁵ḍ間違って計算しない限り、UTF-8では15バイトです。
ta.speot.is

7

MATL、10バイト

間違いを指摘してくれた@Zgarbに感謝します。

IlhY"s10\~

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

説明

Ilh     % Push [1 3]
Y"      % Implicit input. Run-length decoding. For each entry in the
        % first input, this produces as many copies as indicated by
        % the corresponding entry of the second input. Entries of
        % the second input are reused cyclically
s       % Sum of array
10\     % Modulo 10
~       % Logical negate. Implicit display

7

Befunge-98(PyFunge)16 14バイト

sのj代わりにを使用して2番目の部分をスキップし、2番目の部分を;削除するために最初の部分~とを交換して2バイトを節約++ました。

~3*+~+6jq!%a+2

入力は8桁(該当する場合は先頭に0が付きます)で、それ以外は何もありません。

終了コード(TIOのデバッグドロップダウンを開く)を介して出力します。1がtrue、0がfalseです。

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

説明

このプログラムはさまざまなトリックを使用します。

まず、ASCII値を使用して1つずつ数字を取得します。通常、これには、入力から読み取るときに各値から48を引く必要があります。ただし、変更しない場合、合計で48個のコピーが16個(3 + 1 + 3 + 1 + 3 + 1 + 3 + 1)残ります。これは、合計が768より大きいことを意味しますそれが「あるべき」もの。合計mod 10のみを対象としているため、後で合計に2を追加するだけです。したがって、生のASCII値を取り込んで、6バイト程度節約できます。

次に、このコードは入力が8文字のみであることが保証されているため、他のすべての文字がEOFであるかどうかのみをチェックします。

第三に、#行の最後は最初の文字をスキップしませんが;、他の方向から来る場合はスキップします。これは#;、代わりに前面に配置するよりも優れています。

プログラムの2番目の部分は1回だけ実行されるため、逆方向に実行するときに前半をスキップするように設定する必要はありません。これにより、逆方向に実行する前に終了するため、jumpコマンドを使用して後半をジャンプできます。

ステップバイステップ

注:「奇数」および「偶数」の文字は、0インデックスシステムに基づいています。最初の文字は偶数で、インデックス0です。

~3*+~+      Main loop - sum the digits (with multiplication)
~           If we've reached EOF, reverse; otherwise take char input. This will always
                be evenly indexed values, as we take in 2 characters every loop.
 3*+        Multiply the even character by 3 and add it to the sum.
    ~       Then, take an odd digit - we don't have to worry about EOF because
                the input is always 8 characters.
     +      And add it to the sum.
      6j    Jump over the second part - We only want to run it going backwards.

        q!%a+2    The aftermath (get it? after-MATH?)
            +2    Add 2 to the sum to make up for the offset due to reading ASCII
          %a      Mods the result by 10 - only 0 if the bar code is valid
         !        Logical not the result, turning 0s into 1s and anything else into 0s
        q         Prints the top via exit code and exits


6

Wolfram言語(Mathematica)26 21バイト

10∣(2-9^Range@8).#&

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

入力を8桁のリストとして受け取ります。

使い方

2-9^Range@8は10を法とする合同2-(-1)^Range@8であり、である{3,1,3,1,3,1,3,1}。このリストの内積と入力を取り、結果が10で割り切れるかどうかを確認します。

Wolfram言語(Mathematica)、33バイトおよび非競合

Check[#~BarcodeImage~"EAN8";1,0]&

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

入力を文字列として受け取ります。1有効なバーコードと0無効なバーコードを返します。

使い方

組み込みの方法で見つけることができる最高のもの(Mathematicaはそれらすべてであるため)。

内部ビット、#~BarcodeImage~"EAN8";1はEAN8バーコードの画像を生成し、それを完全に無視して1と評価します。ただし、バーコードが無効な場合はBarcodeImage、警告を生成し、Checkキャッチし、その場合は0を返します。


3
計算が短いのか、WolframのValidateEAN8BarCode()関数が標準ライブラリのどこかにまだないので、手作業で計算していますか?
マーク

1
@Mark Mathematica はバーコードを直接検証できません、バーコードBarcodeImageの画像を生成し、プロセスでバーコードを検証するを見つけました。だから、Check[#~BarcodeImage~"EAN8";0,1]<1&働くだろう(それは長いのです)。
ミシャラヴロフ

5

Java 8、58 56 55バイト

a->{int r=0,m=1;for(int i:a)r+=(m^=2)*i;return r%10<1;}

@RickHitchcockの間接的なおかげで、JavaScriptの回答で見た後では(m=4-m)*iなく、使用して-2バイトにm++%2*2*i+iなりました。 -1の代わりに@ETHProductions(および@RickHitchcock)を使用して間接的に感謝します。
(m^=2)*i(m=4-m)*i

説明:

ここで試してみてください。

a->{              // Method with integer-array parameter and boolean return-type
  int r=0,        //  Result-sum
      m=1;        //  Multiplier
  for(int i:a)    //  Loop over the input-array
    r+=           //   Add to the result-sum:
       (m^=2)     //    Either 3 or 1,
       *i;        //    multiplied by the digit
                  //  End of loop (implicit / single-line body)
  return r%10<1;  //  Return if the trailing digit is a 0
}                 // End of method

1
トリック@ETHProductionsが見せてくれたとあなたは別のバイトを保存することができます:変更m=4-mするにm^=2
リックヒッチコック

@RickHitchcockああ、もちろん..私は使用^=1私が間を変更したいときの答えにはかなり頻繁に01^=2この場合、1との間で変更し3ます。素敵なトリック、そしてそれを言及するコメントをありがとう。:)
ケビンクルイッセン

4

05AB1E、14バイト

θ¹¨3X‚7∍*O(T%Q

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

先頭に0sが必要で、数字のリストを取ります。


失敗するようです3100004(真実であるはずです)。
ズガルブ

@Zgarbあなたはそこにいません0
エリックアウトゴルファー

ああ、それは文字列を取りますか?さて、私の悪い。
-Zgarb

@Zgarbさて、引用符は省略できますが、はい、先頭のが必要0です。この回答では、実際に05AB1Eの機能の1つである文字列に数値関数を使用しています。
エリックアウトゴルファー

@ Mr.Xcoder質問はそれについてあまり明確ではありません。それを処理する別のコードを以下に追加します。
エリックアウトゴルファー

4

Pyth、8バイト

!es+*2%2

すべてのテストケースを検証してください!

Pyth、13バイト

入力が常に正確に8桁であると仮定できる場合:

!es.e*bhy%hk2

すべてのテストケースを検証してください!


これはどのように作動しますか?

!es + * 2%2〜完全なプログラム。

      %2〜入力[:: 2]。入力の2番目の要素ごと。
    * 2〜ダブル(リストを2回繰り返す)。
   +〜入力を追加します。
  s〜合計。
 e〜最後の桁。
!〜論理否定。
!es.e * sbhy%hk2〜完全なプログラム。

               〜入力を文字列に変換します。
   .e〜列挙されたマップ。現在の値をbに、インデックスをkに保存します。
          %hk2〜インデックスの逆パリティ。(k + 1)%2。
        hy〜ダブル、インクリメント。これにより、奇数の整数が1に、偶数の整数が3にマッピングされます。
      b〜現在の数字。
     *〜乗算します。
  s〜合計。
 e〜最後の桁。
!〜論理否定。

適用後の最初の7桁の合計が10から減算され、最後の桁と比較される場合、これはアルゴリズムが適用された後のすべての桁の合計が10の倍数であるかどうかをチェックすることと同じです。


失敗するようです3100004(真実であるはずです)。
ズガーブ

@Zgarb待つべきです3*3+1*1+0*3+...か、それとも0*3+3*1+1*0..?私たちは、かつての操作を行うことになっていると思った
氏Xcoder

新しい仕様では、正確に8桁になるように先行桁が追加されています(正しく理解できる場合)。
ズガーブ

@Zgarb OK、修正済み。
ミスターXcoder


4

網膜23 22バイト

マーティン・エンダーのおかげで-1バイト!

(.).
$1$1$&
.
$*
M`
1$

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

説明

入力例: 20378240

(.).
$1$1$&

各桁の数字を、最初の数字を2回繰り返した後、その数字自体に置き換えます。我々が得る2220333788824440

.
$*

各桁を単項に変換します。明確にするために括弧を追加すると、(11)(11)(11)()(111)(111)...

M`

空の文字列の一致数をカウントします。これは、文字列内の1の数よりも1つ多くなります。(最後の2つのステップでは、基本的に各数字の合計+1を取得しました)結果:60

1$

1文字列の末尾に一致します。有効なバーコードのために、数字を3と1を交互に乗算して合計しました。これは10で割り切れます(最後の数字0)。ただし、最後のステップで1を追加したため、最後の数字を1にする必要があります。最終結果:1


2
.マッチステージにドロップ1$して、最後にマッチできると思います。
マーティンエンダー

@MartinEnder非常に素晴らしい、私はそれをします、ありがとう!
レオ

3

PowerShell、85バイト

param($a)(10-(("$a"[0..6]|%{+"$_"*(3,1)[$i++%2]})-join'+'|iex)%10)%10-eq+"$("$a"[7])"

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

定義されたアルゴリズムを実装します。入力を受け取り$a、で各桁を引き出し"$a"[0..6]、でループします|%{...}。各反復では、数字を取得し、文字列"$_"としてキャストしてから、整数としてキャストした後+、いずれか3または1$iモジュロをインクリメントすることによって選択されます2)を乗算します。

それらの結果はすべて集められ、合計され-join'+'|iexます。その結果modを取得し10、から減算し10、再び結果modを取得10します(この2番目のmodは00000000テストケースを説明するために必要です)。次に、それ-eqが最後の桁に当てはまるかどうかを確認します。そのブール結果はパイプラインに残り、出力は暗黙的です。


失敗するようです3100004(真実であるはずです)。
-Zgarb

@Zgarbは私のために働きますか?オンラインでお試しください!
AdmBorkBork

ああ、引用符なしでテストしました。
ズガーブ

@Zgarbああ、そう。引用符がないと、PowerShellは暗黙的に整数としてキャストされ、先頭のゼロが削除されます。
AdmBorkBork

3

ゼリー、16バイト

ż3,1ṁ$P€SN%⁵
Ṫ=Ç

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

入力を数字のリストとして受け取ります


Nitpick:TIOタイムアウト。また、16バイト
エリックアウトゴルファー

@EriktheOutgolferなんて待って。Dフッターに入れると動作します。ええ、ありがとう!:D
HyperNeutrino

@EriktheOutgolfer私は何か間違ったことをしていますか?16バイトが無効のようです。
ハイパーニュートリノ

たぶん、それはちょっと違って機能しますが、あなたのものも少し無効に思えます...具体的には、最後の行はであるべきだと思いますDµṪ=Ç
エリックアウトゴルファー

1
失敗するようです3100004(真実であるはずです)。
ズガルブ

3

APL(Dyalog)、14バイト

ストリートスターのソリューションと同等。

完全なプログラム本体。STDINからの番号のリストのプロンプト。

0=10|+/⎕×83 1

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

は…

0= ゼロに等しい

10| mod-10

+/ 合計

⎕× 入力時間

8⍴3 1 から周期的に取得される8つの要素 [3,1]


1
APLは、古代シュメール語や線形Bのようなものから1つの文字でそれを行うことはできませんか?
マーク

列車:0 = 10 |-/ + 2×+ /
ngn

3

05AB1E、9バイト

3X‚7∍*OTÖ

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

3X‚7∍*OTÖ    # Argument a
3X‚          # Push [3, 1]
   7∍        # Extend to length 7
     *       # Multiply elements with elements at same index in a
      O      # Total sum
       TÖ    # Divisible by 10

いいね!私が最初に考えたのは、これを見たときに「長さを伸ばす」ことでした。
魔法のタコUr

31×S*OTÖ8バイトの場合。×31 n回押すだけです。乗算すると、余分な31が自動的に削除されます。
魔法のタコUr

第六テストケースに失敗しているようだ@MagicOctopusUrn69165430 -> 1
kalsowerus

3

J、17バイト

コールのおかげで-10バイト

0=10|1#.(8$3 1)*]

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

これは、同じサイズのリストの乗算を使用して元のソリューションのzip / multiplyコンボを回避し1#.、製品を一緒に追加する「ベース1トリック」を使用します。高レベルのアプローチは、元の説明に似ています。

オリジナル、27バイト

0=10|{:+[:+/[:*/(7$3 1),:}:

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

説明した

0 =                                        is 0 equal to... 
    10 |                                   the remainder when 10 divides...
         {: +                              the last input item plus...
              [: +/                        the sum of...
                    [: */                  the pairwise product of...
                          7$(3 1) ,:       3 1 3 1 3 1 3 zipped with...
                                     }:    all but the last item of the input

0=10|1#.(8$3 1)*]17バイトで動作するはずです(同じアルゴリズムでも動作します)。アイムかなりので、必ずベータ版であなたは名詞と右側に終わったフックを持つことができることを0=10|1#.]*8$3 115のために働くことが(私はョを確認したいが、ダウンしているようだ?)
コール

@コール、私はこの改善が大好きです。1#.2〜3回のトリックを知って忘れてしまった…思い出させてくれてありがとう。ところで、15バイトバージョンはTIOで動作しませんでした。
ジョナ

3

C(gcc)、84 82 72 61 54バイト

c;i;f(x){for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;c=c%10<1;}

ニールから-21バイト

Nahuel Fouilleulから-7バイト

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

Steadyboxの答えとは独立して開発

「f」はバーコードをとして受け取り、TrueおよびFalse intを返す関数です。10

  • f店舗の最後の桁xss=x%10)を、

  • 次に、cfor(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;)の合計を計算します

    • c合計、iカウンタです

    • 最初の数字を含む各数字について1+2*i%4、数字(x%10)をチェックサムに加算し、増分ii++in 3-2*i++%4

      • 1+2*i%4偶数の場合は1、奇数のi場合iは0
  • 次に、合計が10の倍数であるかどうかを返します。最後の桁(1を乗算)を追加したため、バーコードが有効な場合、合計は10の倍数になります。(GCC依存の未定義の動作を使用して省略しますreturn)。


とにかく後で取っているように(x%10)できると思います。また、最後にゼロかどうかを使用してテストできると思います。xc%10i<8c%10
ニール

@ニールありがとう!-10バイトになりました。
pizzapants184

実際、私sは不必要だと思う:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
ニール

TIOリンクは61バイトですが、回答では72バイトです。また、理由がわからない、x=c%10<1またはまだ動作するc=c%10<1代わりにreturn c%10<1
Nahuel Fouilleul

また、i<8置き換えることができx
ナウエルFouilleul

3

C、63バイト

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

それは前提とし0ているtrueと、他の値ですfalse

戻り値を改善するための+3バイト

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10==0;}

ステートメントに追加==0returnます。

非ゴルフ

int check(int* values)
{
    int result = 0;
    for (int index = 0; index < 8; index++)
    {
        result += v[i] * 3 + v[++i]; // adds this digit times 3 plus the next digit times 1 to the result
    }
    return result % 10 == 0; // returns true if the result is a multiple of 10
}

これは、チェックディジットを含むバーコード全体のチェックサムが10の倍数になるようにチェックディジットが選択されるEANチェックサムの代替定義を使用します。

Steadyboxが示唆するループ内の変数の初期化、63バイト

i;s;c(int*v){for(i=s=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

Steadyboxで推奨されている中括弧の削除、61バイト

i;s;c(int*v){for(i=s=0;i<8;i++)s+=v[i]*3+v[++i];return s%10;}

Kevin Cruijssenによって提案されているように、より良い戻り値<1ではなく使用==0

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10<1;}

ステートメントに追加<1すると、3バイトreturnが追加されるの==0ではなく、2バイトのみが追加されます。


の後を削除することにより、2バイト保存できます。また、機能の提出は再利用可能である必要はありますが、初期化する必要があるので、(単に変更する関数の内部にしてまで)。{}forsi;s=0;i,s;i=0;i=s=0;
Steadybox

@Steadybox中括弧を削除するにはどうすればよいですか?
マイケルジョンソン

それらの内部には1つのステートメントのみがあります。の後forに中括弧がない場合、ループ本体が次のステートメントになります。for(i=0;i<8;i++){s+=v[i]*3+v[++i];}はと同じfor(i=0;i<8;i++)s+=v[i]*3+v[++i];です。
Steadybox

@Steadyboxああ、もちろん。それは、通常のコードを書くとき、コードが読みやすくなるので、不要な場合でも常に中括弧を含めるため、私が通常忘れているC構文の癖の1つです。
マイケルジョンソン

真/偽の回答では、追加==0することで+3の代わりに、代わりに使用することで+2にすることができます<1。:)
ケビンクルーイッセン

2

JavaScript(Node.js)、47バイト

e=>eval(e.map((a,i)=>(3-i%2*2)*a).join`+`)%10<1

すでにかなり短い答えがありますが、これはJavaScriptでゴルフをする最初の試みなので、ゴルフに関する推奨事項を聞きたいです:-)

テスト中

または、オンラインで試すことができます!


2

Perl 5の、37 32 + 1(-p)バイト

s/./$-+=$&*(--$|*2+1)/ge;$_=/0$/

Dom Hastingsのおかげで-5バイト。37 +1バイトは

$s+=$_*(++$i%2*2+1)for/./g;$_=!!$s%10

オンラインで試す


1
これで少し遊んで、有用なトリックを共有すると思った:との--$|1を切り替える0ので++$i%2、交互のブール値の代わりにそれを使用できます!また、重要なのは、合計($s)が一致し/0$/、それらの変更を組み合わせて33バイトを取得することですs///オンラインで試してみてください!(-l単に可視性のためです)
ドムヘイスティングス

はい私はにかかわらず、s/./(something with $&)/geとに/0$/一致ではなく、2組み合わせます。
ナウエルフイユル

2

Brainfuck、228バイト

>>>>++++[<++>-]<[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]>[->]<<<<[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]>>>>[>>[<<[>>+<<-]]>>]<<<++++[<---->-]+++++[<++<+++>>-]<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

おそらくかなり改善できます。入力は一度に1桁で、真の場合は1、偽の場合は0を出力します。

使い方:

>>>>++++[<++>-]<

位置3に8を置きます。

[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]

入力を8回受け取り、毎回ascii値から実際の値+2に変更します。入力は1ずつ間隔が空けられ、後で簡単に乗算できるように削除されます。

>[->]

各アイテムから1つを引きます。テープは次のようになります

0 0 0 0 4 0 4 0 8 0 7 0 6 0 2 0 3 0 10 0 0
                                         ^

各値が1を超えている必要があります。これは、ゼロが乗算プロセスを台無しにするためです。

これで乗算を開始する準備が整いました。

<<<<

最後から2番目の項目に移動します。

[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]

ゼロのときに、現在のアイテムに3を掛けてから、2つのアイテムを左に移動します。これで、必要なものがすべて3倍になり、テープの最初の位置にいます。

>>>>[>>[<<[>>+<<-]]>>]

リスト全体を合計します。

<<<++++[<---->-]

持っている値は、実際の値よりも16多いです。これを修正するには、16を引きます。

+++++[<++<+++>>-]

合計が10の倍数であるかどうかをテストする必要があります。最大合計は、すべての9で144です。合計が10 * 15を超えることはないので、テープに15と10をこの順序で入れます。合計の右。

<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]

15に移動します。ゼロではありませんが、合計がゼロでないかどうかをテストします。ある場合は、10を引きます。これで、(空の)合計ポジション、または(空の)10ポジションのいずれかになります。1つ右に移動します。合計ポジションにいた場合、ゼロ以外の15ポジションにいます。その場合、右に2回移動します。今、私たちは両方のケースで同じ立場にいます。10の位置に10を加え、15の位置から1を引きます。

残りは出力用です:

<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

合計位置に移動します。ゼロ以外(負)の場合、バーコードは無効です。位置を-1に設定します。49を追加して正しいASCII値を取得します。有効な場合は1、無効な場合は0です。


2

Java 8、53バイト

ゴルフ:

b->(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

ラムダでの直接計算は、最短のソリューションに見えます。単一の式に収まり、ラムダオーバーヘッドを最小化し、無関係な変数宣言とセミコロンを削除します。

public class IsMyBarcodeValid {

  public static void main(String[] args) {
    int[][] barcodes = new int[][] { //
        { 2, 0, 3, 7, 8, 2, 4, 0 }, //
        { 3, 3, 7, 6, 5, 1, 2, 9 }, //
        { 7, 7, 2, 3, 4, 5, 7, 5 }, //
        { 0, 0, 0, 0, 0, 0, 0, 0 }, //
        { 2, 1, 0, 3, 4, 9, 8, 4 }, //
        { 6, 9, 1, 6, 5, 4, 3, 0 }, //
        { 1, 1, 9, 6, 5, 4, 2, 1 }, //
        { 1, 2, 3, 4, 5, 6, 7, 8 } };
    for (int[] barcode : barcodes) {
      boolean result = f(b -> (3 * (b[0] + b[2] + b[4] + b[6]) + b[1] + b[3] + b[5] + b[7]) % 10 < 1, barcode);
      System.out.println(java.util.Arrays.toString(barcode) + " = " + result);
    }
  }

  private static boolean f(java.util.function.Function<int[], Boolean> f, int[] n) {
    return f.apply(n);
  }
}

出力:

[2, 0, 3, 7, 8, 2, 4, 0] = true
[3, 3, 7, 6, 5, 1, 2, 9] = true
[7, 7, 2, 3, 4, 5, 7, 5] = true
[0, 0, 0, 0, 0, 0, 0, 0] = true
[2, 1, 0, 3, 4, 9, 8, 4] = false
[6, 9, 1, 6, 5, 4, 3, 0] = false
[1, 1, 9, 6, 5, 4, 2, 1] = false
[1, 2, 3, 4, 5, 6, 7, 8] = false

2

QBasic、54 52バイト

うーん、退屈な答えは最短であることが判明しました:

INPUT a,b,c,d,e,f,g,h
?(3*a+b+3*c+d+3*e+f+3*g+h)MOD 10=0

これは、コンマ区切りの数字を入力します。一度に1桁ずつ入力する私の元の54バイトソリューションは、「より良い」アプローチを使用します。

m=3
FOR i=1TO 8
INPUT d
s=s+d*m
m=4-m
NEXT
?s MOD 10=0

2

C#(.NET Core)65 62バイト

b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}

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

謝辞

@KevinCruijssenと、排他的論理和演算子を使用した巧妙なトリックのおかげで、-3バイトになりました。

デゴルフド

b=>{
    int s=0,i=0,t=1;

    while(i<8)
        s+=b[i++]*(t^=2); // exclusive-or operator alternates t between 3 and 1.

    return s%10<1;
}

C#(.NET Core)、53バ​​イト

b=>(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

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

@ Snowman's answerの直接ポート。


あなたの最初の答え:b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}62バイト)、または代わりにforeachで、また62バイト:(b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}これは私のJava 8回答のポートです)。
ケビンCruijssen

1

MATLAB / オクターブ、32バイト

@(x)~mod(sum([2*x(1:2:7),x]),10)

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

他のOctaveの回答にもかかわらず、他の回答を見ずにこのコードとアプローチを開発したので、これを投稿します。

ここには、入力を8つの値の配列として受け取り、有効なバーコードの場合はtrue、そうでない場合はfalseを返す匿名関数があります。

結果は次のように計算されます。

              2*x(1:2:7)
             [          ,x]
         sum(              )
     mod(                   ,10)
@(x)~
  1. 奇数(1インデックス)に2を掛けます。
  2. 結果は入力配列の先頭に追加され、合計が奇数桁を3回、偶数桁を1回含む配列を提供します。
  3. 合計を実行します。この合計には、指定されたチェックサムも含まれます。
  4. 次に、モジュロ10が実行されます。提供されたチェックサムが有効な場合、チェックサム値を含むすべての乗算された数字の合計は10の倍数になります。したがって、有効なバーコードのみが0を返します。
  5. 結果は、有効な場合は論理出力trueを取得するために反転されます。

1

Excel、37バイト

「8つの整数のリスト」をExcelで8つの独立したセルを許可するものとして解釈する:

=MOD(SUM(A1:H1)+2*(A1+C1+E1+G1),10)=0

= MOD(SUM((A1:H1)+ 2 *(A1 + C1 + E1 + G1))、10)= 0この数式はExcelに存在しますか?
RosLuP

@RosLuP、事前定義されていない、いいえ。しかし、モジュロ、合計、+など;-)
ヴェルニッシュ

APLでは、最初にy =(A1:H1)+ 2 *(A1 + C1 + E1 + G1)がうまくいき、合計とmodの後がうまくいくようです。APLでは、最初のsum(A1:H1)などはうまくいきません。(1,2,3)+ 4 =(5,6,7)などであり、sum(5,6,7)= 18ではありません。sum(1,2,3)= 6および6 + 4 = 10は18とは異なることに注意してください。しかし、何かエラーが発生する可能性があります
-RosLuP

@RosLuP、謝罪、()あなたのコメントの変更されたsを逃しました。
ヴェルニッシュ

問題は、Excelの解釈方法=(A1:H1)です。これは配列として処理されません。A-H範囲外の列に配置されている場合は無効です。AHの列に配置されている場合、その列の値のみを返します。(%の式は%になります:C2-> C1 H999-> H1 K1-> #VALUE!)
ヴェルニッシュ

1

Ruby、41バイト

整数の配列を取ります。ヨルダンのおかげで-6バイト。

->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}

いいね!mapここではまったく必要ありませんzipが、ブロックします。あなたは使ってカップルより多くのバイトを保存することができます$.代わりに初期化s->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
ヨルダン

1

TI-Basic(83シリーズ)、18バイト

not(fPart(.1sum(2Ans-Ans9^cumSum(binomcdf(7,0

入力をリストとして取得します Ans1有効なバーコードと0無効なバーコードを返します。

私のポート Mathematicaの回答の。オンラインテスト環境の代わりに、スクリーンショットが含まれます。

バーコードのスクリーンショット

注目すべき機能: binomcdf(7,0リストを生成するために使用されます{1,1,1,1,1,1,1,1}(成功確率0の7回の試行から、N = 0,1、...、7の場合、最大N回の成功がある確率のリスト)。次に、cumSum(これをに変換し{1,2,3,4,5,6,7,8}ます。

これは、seq(コマンドを使用するよりも1バイト短くなりますが、歴史的には、これも大幅に高速であるという点でした。

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