Barkodum geçerli mi?


33

Bir EAN-8 barkodu, 7 basamaklı bilgi ve 8. kontrol toplamı içerir.

Sağlama toplamı, basamakları sırayla 3 ve 1 ile çarparak, sonuçları ekleyerek ve 10'un bir sonraki katından çıkartarak hesaplanır.

Örneğin, rakamları verilen 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

Bu elde edilen basamak toplamı 55 sağlama basamaklı yani, 55 = 5-60


Meydan okuma

Göreviniz, 8 basamaklı bir barkod verildiğinde, geçerli olup olmadığını doğrulamaktır - sağlama toplamı geçerliyse bir gerçeğe uygun değer döndürmek ve aksi takdirde sahte olur.

  • Aşağıdaki formlardan birinde girdi alabilirsiniz:
    • Barkod hanelerini temsil eden, 8 karakter uzunluğunda bir dize
    • 8 tamsayının bir listesi, barkodun rakamları
    • Negatif olmayan bir tam sayı (hiç kimsenin verilmediği baştaki sıfırları varsayabilirsin, yani 1= 00000001veya verilen sıfırlarla giriş talep edebilirsiniz)
  • EAN-8 sağlama toplamını hesaplayan (yani, ilk 7 basamağı ve sonunu hesaplayanlar) yasaklanmıştır.
  • Bu , yani en kısa program (bayt cinsinden) kazanır!

Test Kılıfları

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

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


1
Bu soru aslında bir barkodla (siyah-beyaz çizgili şey değildir) değil, bir barkodla kodlanan rakamlarla ilgilidir. Sayı bir barkod olmadan da olabilir ve barkod, EAN'lardan başka şeyleri kodlayabilir. Belki de " EAN-8'im geçerli mi " daha iyi bir başlık olabilir mi?
Paŭlo Ebermann 15:17

2
@ PaŭloEbermann oldukça ... aynı ona çal yok
FlipTack

7
Barkodları okurken, bir checksum doğrulamak değil, bazı görüntü okuma (veya en azından bir bit-string) bekliyorum.
Paŭlo Ebermann 15:17

Güçlü bir ilişki , çünkü bir ISBN-13 bir EAN'dir.
Olivier Grégoire

Yanıtlar:


5

Jöle , 7 bayt

s2Sḅ3⁵ḍ

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

@ETHProductions sayesinde 2 byte, @Craig Ayre sayesinde 1 byte kaydedildi.

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

Girdiyi basamak listesi olarak alır.

Sağlama toplamı dahil tüm basamakların toplamını belirler.

Toplam 10'un katı ise, geçerli bir barkoddur.

Test Kılıfları


Ön-tekrarlamadan tekrarlama ile tekrarlamadang=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1
sonraya

Teşekkürler, @ETHproductions, ben değiştim map, ki girdi bir dize yerine rakamların bir listesi olabileceğinden daha iyi sonuç verdiğini düşünüyorum.
Rick Hitchcock

Belki başka bir byte ile kaydetmek s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1?
ETHProductions,

Evet, zekice, teşekkürler
Rick Hitchcock

Harika çözüm! Değiştirmek Could &&ile |truthy beri çıkış 1/0 / falsy izin verilir?
Craig Ayre


8

Jöle , 8 bayt

m2Ḥ+µS⁵ḍ

Test odasını dene.

Jöle , 9 bayt

JḂḤ‘×µS⁵ḍ

Çevrimiçi deneyin veya test takımını deneyin.

Bu nasıl çalışır

m2Ḥ + µS⁵ḍ ~ Tam program.

m2 ~ Modüler 2. Girişin her ikinci elemanını döndür.
  Each ~ Her iki katı.
   + µ ~ Girişi ekleyin ve yeni bir monadik zincir başlatın.
     S ~ Sum.
      ~ 10 ile bölünebilir mi?
JḂḤ '× µS⁵ḍ ~ Tam program (monadik).

J ~ 1 indeksli uzunluk aralığı.
 Bit ~ Bit; Modulo her aralıktaki sayıyı 2'ye kadar.
  Each ~ Her iki katı.
   '~ Her artış.
    × ~ Giriş ile çift yönlü çarpma.
     µ ~ Yeni bir monadik zincir başlatır.
      S ~ Sum.
       Sum ~ Toplam 10 ile bölünebilir mi?

Barkodun ilk 7 basamağının ve sağlama toplamının sonucunun geçerli olması için 10 katına eklemesi gerekir . Bu nedenle sağlama toplamı, tüm listeye uygulanan algoritma 10 ile bölünebiliyorsa geçerlidir .


Hala 9 bayt ama tutarlı değerlere sahip:JḂḤ‘×µS⁵ḍ
HyperNeutrino 15:17

@HyperNeutrino Teşekkürler, bunun için bir atom olduğunu biliyordum!
Bay Xcoder

Ayrıca 9 byte:: JḂaḤ+µS⁵ḍP
HyperNeutrino

@HyperNeutrino Pek çok alternatif var: P
Bay Xcoder

1
8 bayt veya 8 karakter? m2Ḥ+µS⁵ḍyanlış hesapladıysam, UTF-8’de 15 bayttır.
ta.speot.is 18:17

7

MATL , 10 bayt

@Zgarb'a bir hatayı işaret ettiği için teşekkürler , şimdi düzeltildi.

IlhY"s10\~

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

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 bayt

İkinci kısmı s jyerine kullanarak atlamanın ;yanı sıra , ikinci kısımda kurtulmak için a ~ve +birinci kısımları değiştirerek 2 bayt kurtarıldı +.

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

Giriş, 8 basamaklıdır (eğer varsa baştaki 0 ​​ile) ve başka bir şey yoktur.

Çıkış kodu ile çıkışlar (TIO'da hata ayıklama açılır penceresini açın), 1 doğru ve 0 yanlış.

Çevrimiçi deneyin!

açıklama

Bu program çeşitli hileler kullanır.

Her şeyden önce, ASCII değerleri üzerinden rakamları birer birer alır. Normalde bu, girdiden okuduğumuz gibi her değerden 48'in çıkarılmasını gerektirir. Bununla birlikte, değiştirmezsek, toplamda 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) 48 adet fazladan kopya kalır ve bu da toplamımızın 768 daha büyük olacağı anlamına gelir. "olması gerektiği". Sadece toplam mod 10 ile ilgilendiğimiz için, sonradan toplamı 2 ekleyebiliriz. Böylece, ham ASCII değerlerini alabiliriz, böylece 6 bayt tasarruf sağlayabiliriz.

İkincisi, bu kod yalnızca diğer karakterlerin bir EOF olup olmadığını denetler, çünkü girişin yalnızca 8 karakter uzunluğunda olması garanti edilir.

Üçüncüsü, #satırın sonundaki ilk karakteri atlamaz, ancak ;diğer yönden gelenleri atlar . Bunun #;yerine cepheye koymaktan daha iyidir .

Programımızın ikinci kısmı yalnızca bir kez çalıştırıldığından, geriye doğru çalışırken ilk yarıyı atlayacak şekilde ayarlamak zorunda değiliz. Bu, geri gitmeden çalıştırmadan önce çıkarken, ikinci yarının üstünden atlamak için jump komutunu kullanmamızı sağlar.

Adım adım

Not: "Tek" ve "Çift" karakterleri 0 dizinli bir sistemi temel alır. İlk karakter, dizin 0 ile eşit bir karakterdir.

~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 Dili (Mathematica) , 26 21 bayt

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

Çevrimiçi deneyin!

Girişi 8 basamaklı bir liste halinde alır.

Nasıl çalışır

2-9^Range@8eşittir modulo 10 2-(-1)^Range@8, ki bu {3,1,3,1,3,1,3,1}. Bu listenin nokta ürününü girdi ile alıyoruz ve sonucun 10'a bölünebilir olup olmadığını kontrol ediyoruz.

Wolfram Dili (Mathematica) , 33 bayt ve rekabet etmeyen

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

Çevrimiçi deneyin!

Bir dize olarak girdi alır. 1Geçerli barkodlar ve 0geçersiz olanlar için döndürür .

Nasıl çalışır

Yerleşik olarak bulabileceğim en iyi şey (çünkü Mathematica tamamen bunlarla ilgilidir).

İçinde biraz #~BarcodeImage~"EAN8";1, daha sonra tamamen göz ardı eder ve barkod geçersiz ise değerlendirir Ancak 1'e, daha sonra, EAN8 barkod bir görüntü üretir BarcodeImage, bir uyarı oluşturur Checkbu durumda 0 dönen, yakalar.


3
Hesaplamayı elle mi yapıyorsunuz, çünkü daha kısa ya da Wolfram'ın standart kütüphanesinde bir yerde bir ValidateEAN8BarCode () işlevi yok mu?
Mark

1
@Mark Mathematica doğrudan barkodu doğrulayamaz , ancak ben sadece buldum BarcodeImage, ki bu barkodun görüntüsünü oluşturur ve işlemdeki barkodu doğrular. Böylece Check[#~BarcodeImage~"EAN8";0,1]<1&işe yarar (ama daha uzun).
Misha Lavrov

5

Java 8, 58 56 55 bayt

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

@RickHitchcock sayesinde dolaylı olarak -2 bayt , JavaScript cevabını gördükten sonra kullanmak (m=4-m)*iyerine . -1 byte dolaylı olarak @ETHProductions (ve @RickHitchcock ) kullanarak yerine .m++%2*2*i+i
(m^=2)*i(m=4-m)*i

Açıklama:

Burada dene.

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
Bir hile @ETHProductions bana gösterdi ile başka byte kaydedebilirsiniz: değişikliğini m=4-miçin m^=2.
Rick Hitchcock

@RickHitchcock Ah, elbette .. ve ^=1arasında geçiş yapmak istediğimde cevaplarda oldukça sık kullanıyorum . Bu durumda eserler arasında değiştirmeye ve . Güzel hile ve yorum yapmak için teşekkür ederim. :)01^=213
Kevin Cruijssen

4

05AB1E , 14 bayt

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

Çevrimiçi deneyin!

İhtiyacı olan 0s, basamakların listesini alır.


Başarısız görünüyor 3100004(truthy olmalı).
Zgarb

@ Zgarb Bir 0orada eksik .
Outgolfer Erik,

Oh, bir ip mi alıyor? Tamam o zaman benim hatam.
Zgarb

@Zgarb Peki, alıntıları ihmal edebilirsiniz, ama evet, öncüye ihtiyacınız var 0. Bu cevap aslında 05AB1E'nin özelliklerinden biri olan dizgelerde sayı fonksiyonlarını kullanır.
Outgolfer Erik

@ Mr.Xcoder Bu konuda soru çok net değil, aşağıda bunun için işleyen başka bir kod ekleyeceğim.
Outgolfer Erik

4

Pyth , 8 bayt

!es+*2%2

Tüm test durumlarını doğrulayın!

Pyth , 13 bayt

Girişin her zaman tam olarak 8 rakamı olduğunu varsayabiliriz:

!es.e*bhy%hk2

Tüm test durumlarını doğrulayın!


Bu nasıl çalışıyor?

! es + * 2% 2 ~ Tam program.

      % 2 ~ Giriş [:: 2]. Girişin her ikinci elemanı.
    * 2 ~ Double (listeyi iki kez tekrarla).
   + ~ Girişi ekleyin.
  s ~ Sum.
 e ~ Son basamak.
! Mantıksal DEĞİL.
! es.e * sbhy% hk2 ~ Tam program.

               ~ Girişi bir dizeye dönüştürün.
   .e ~ Geçerli harita değerini b olarak ve dizini k olarak kaydederek numaralandırılmış harita.
          % hk2 ~ Dizinin ters paritesi. (k + 1)% 2.
        hy ~ Çift, artış. Bu, tek tam sayılarını 1'e, hatta 3'e eşleştirir.
      b ~ Geçerli hane.
     * ~ Çarpın.
  s ~ Sum.
 e ~ Son basamak.
! Mantıksal olumsuzlama.

Eğer uygulandıktan sonra ilk 7 hanenin toplamı algoritma 10'dan çıkarılır ve sonra son haneye kıyasla, bu, algoritma uygulandıktan sonra tüm basamakların toplamının 10 katı olup olmadığını kontrol etmeye eşdeğerdir .


Başarısız görünüyor 3100004(truthy olmalı).
Zgarb

Bekle @Zgarb yapmalıyız 3*3+1*1+0*3+...ya 0*3+3*1+1*0..? Eski yapmamız gerektiğini düşündüm
Bay Xcoder

Yeni spesifikasyonda, tam olarak 8 olduğundan emin olmak için öncü rakamlar eklenir (doğru anlıyorsam).
Zgarb

@ Zgarb Tamam, düzeltildi.
Bay Xcoder,


4

Retina , 23 22 bayt

Martin Ender'e -1 bayt !

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

Çevrimiçi deneyin!

açıklama

Örnek giriş: 20378240

(.).
$1$1$&

Her hane çiftini, iki kez tekrar eden ilk hane ve ardından çiftin yerine koyun. Alırız2220333788824440

.
$*

Her basamağı birliğe dönüştür. Netlik için parantez eklendiğinde,(11)(11)(11)()(111)(111)...

M`

Boş dizginin eşleşme sayısını, dizgideki sayıdan daha fazla olan sayın. (Son iki adımda temelde her bir basamağın toplamını attık +1) Sonuç:60

1$

1Dizenin sonunda bir a eşleştirin. Rakamları sırayla 3 ve 1 ile çarptık ve topladık, geçerli bir barkod için bu 10'a bölünmelidir (son basamak 0); ancak son adımda 1 tane daha ekledik, bu yüzden son basamağın 1 olmasını istiyoruz 1.


2
Bence .maç sahnesine düşebilir 1$ve sonunda eşleştirebilirsiniz .
Martin Ender

@MartinEnder çok güzel, bunu yapacağım, teşekkürler!
Leo

3

PowerShell , 85 bayt

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

Çevrimiçi deneyin! veya Tüm test durumlarını doğrula

Algoritmayı tanımlandığı şekilde uygular. Girdiyi alır $a, her bir rakamı dışarı çeker "$a"[0..6]ve içlerinden geçirir |%{...}. Her yineleme, basamağı alırız, bir dizge olarak atarız, "$_"sonra +ya 3da ile çarpmadan önce bir int a atarız 1(( $imodulo artırılarak seçilir 2).

Bu sonuçların hepsi bir araya toplanır ve toplanır -join'+'|iex. Bu sonuç modunu alıyoruz 10, bunu 10çıkarıyoruz ve tekrar sonuç modunu alıyoruz 10(bu ikinci mod, 00000000test durumunu hesaba katmak için gereklidir ). Daha sonra -eqbunun son haneye kadar olup olmadığını kontrol ettik . Bu Boolean sonucu boru hattında bırakılır ve çıktı kesindir.


Başarısız görünüyor 3100004(truthy olmalı).
Zgarb

@ Zgarb Benim için çalışıyor mu? Çevrimiçi deneyin!
AdmBorkBork,

Ah tamam, tırnak işaretleri olmadan test ettim.
Zgarb

@Zgarb Ah, evet. Tırnaklar olmadan, PowerShell dolaylı olarak bir tamsayı olarak atacak ve baştaki sıfırları kaldıracaktır.
AdmBorkBork,

3

Jöle , 16 bayt

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

Çevrimiçi deneyin!

basamak listesi olarak girdi alır


Nitpick: TIO zaman aşımlarınız. Ayrıca, 16 bayt .
Outgolfer Erik,

@EriktheOutgolfer Nasıl olduğunu bekleyin. Ben Daltbilgi koymak zaman çalışır . Ve yay teşekkürler! : D
HyperNeutrino

@EriktheOutgolfer Yanlış bir şey mi yapıyorum? 16 baytınız geçersiz görünüyor?
HyperNeutrino

Belki, biraz farklı çalışır, ama sizinki de biraz geçersiz görünüyor ... özellikle de son satırın olması gerektiğini düşünüyorum DµṪ=Ç.
Outgolfer Erik

1
Başarısız görünüyor 3100004(truthy olmalı).
Zgarb

3

APL (Dyalog) , 14 bayt

Streetster'ın çözümü ile eşdeğerdir .

Tam program gövdesi. STDIN’deki numaraların listesini ister.

0=10|+/⎕×83 1

Çevrimiçi deneyin!

Is ...

0= sıfıra eşit

10| mod-10 arasında

+/ toplamı

⎕× giriş zamanları

8⍴3 1 periyodik olarak alınan sekiz element [3,1]

?


1
APL bunu Antik Sümer veya Lineer B gibi bir şeyden tek karakterde yapamaz mı demek istiyorsunuz?
Mark

tren: 0 = 10 | - / + 2 × + /
17'de

3

05AB1E , 9 bayt

3X‚7∍*OTÖ

Çevrimiçi deneyin!

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

Güzel! Düşündüğüm ilk şey, bunu gördüğümde "uzunluğa uzanmak" oldu, bunu henüz kullanmadım.
Magic Octopus Urn

31×S*OTÖ8 bayt için ×Sadece 31 nkez iter . Çarptığınızda, otomatik olarak ekstra 31'i düşürür.
Magic Octopus Urn

@ MagicOctopusUrn Bu 6'ncı 69165430 -> 1
testis

3

J, 17 bayt

Cole sayesinde -10 bayt

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

Çevrimiçi deneyin!

Bu, orijinal çözeltinin sıkıştırılmasını / çoğaltılmasını önlemek için eşit boyutlu listelerin çarpımını 1#.ve ürünleri bir araya getirmek için "temel 1 numarası" nı kullanır. Yüksek seviyeli yaklaşım orijinal açıklamaya benzer.

orijinal, 27 bayt

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

Çevrimiçi deneyin!

açıkladı

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 bayt için çalışması gerekir (aynı algoritmayı da yapar). Ben oldukça bu yüzden emin beta bir isim ile sağ tarafta sona eren bir kanca sahip olabileceği 0=10|1#.]*8$3 115 çalışabilir (ı TiO kontrol ediyorum ama aşağı gibi görünüyor?)
Cole

@ cole, Bu gelişmeyi seviyorum. 1#.2 ya da 3 kez hileyi öğrendim ve unuttum ... bana hatırlattığın için teşekkürler. Oh btw 15 byte versiyonu TIO'da işe yaramadı.
Jonah

3

C (gcc), 84 82 72 61 54 bayt

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

Dan -21 bayt Neil

-7 Nahuel Fouilleul'dan gelen bayt sayısı

Çevrimiçi deneyin!

Bağımsız olarak geliştirilen Steadybox'ın cevabından

'f' barkodu bir olarak alan intve 1Doğru ve 0Yanlış için geri dönen bir fonksiyondur .

  • fxin s( s=x%10) in son basamağını saklar ,

  • Sonra c( for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;) içindeki toplamı hesaplar

    • ctoplamı, ibir sayaç

    • ilki dahil her hane için, sağlama toplamına 1+2*i%4( x%10) basamağını ( ) rakamını ekleyin i( i++giriş 3-2*i++%4)

      • 1+2*i%41 'dir i, hatta 0 olduğunda itek sayı
  • Sonra toplamın on katı olup olmadığını döndürür ve son basamağı eklediğimizden (1 ile çarpılır), barkod geçerli olduğunda toplamın on katı olacaktır. (atlamak için GCC'ye bağlı tanımsız davranış kullanır return).


Bence daha sonra götürdüğün gibi (x%10)olabilir . Ayrıca kullanabileceğinizi ve ardından sadece sıfır olup olmadığını test edebileceğinizi düşünüyorum . xc%10i<8c%10
Neil

@Neil Teşekkürler! -10 bayt var.
pizzapants184

Aslında sgereksiz olduğunu düşünüyorum :c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
Neil

lu bağlantısı 61 bayt ama cevap olarak 72 var, ayrıca neden bilmiyorum x=c%10<1ya c=c%10<1yerine return c%10<1hala çalışır
Nahuel FOUILLEUL

ayrıca i<8değiştirilebilirx
Nahuel Fouilleul

3

C, 63 bayt

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

Varsayar 0olan trueve başka herhangi bir değerdirfalse .

Daha iyi dönüş değeri için +3 bayt

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

ekle ==0içinreturn açıklamada.

Ungolfed

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
}

Bu, kontrol hanesinin seçili olduğu EAN sağlama toplamlarının alternatif tanımını kullanır; öyle ki, kontrol hanesini de içeren tüm barkodun sağlama toplamı 10 katıdır. Matematiksel olarak bu aynı şekilde çalışır ancak yazması çok daha kolaydır.

Değişkenlerin Steadybox tarafından önerildiği şekilde döngü içinde başlatılması, 63 bayt

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

Kıvırcık parantezlerin Steadybox tarafından önerildiği şekilde kaldırılması, 61 bayt

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

Kevin Cruijssen tarafından önerildiği gibi daha iyi getiri değeri <1yerine kullanmak==0

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

Ekle <1için returnaçıklamada, bu eklenmesi yerine, sadece 2 bayt ekler ==03 bayt ekler hangi.


Şunları yapabilirsiniz iki bayt kaydetmek kaldırarak {}sonra for. Ayrıca, işlev gönderimleri yeniden kullanılabilir olması size başlatmak gerekir böylece, s(sadece değiştirmek işlevi içinde i;s=0;için i,s;ve i=0;için i=s=0;).
Steadybox

@Steadybox Kıvrımlı parantezleri nasıl çıkarabilirim?
Micheal Johnson

İçlerinde yalnızca bir ifade var. Sonrasında küme parantezi olmadığında for, döngü gövdesi bir sonraki ifade olacaktır. for(i=0;i<8;i++){s+=v[i]*3+v[++i];}aynıdır for(i=0;i<8;i++)s+=v[i]*3+v[++i];.
Steadybox

@Steadybox Tabii ki. Bu, genellikle unuttuğum C sözdiziminin tuhaflıklarından biridir, çünkü normal kod yazarken, gereksiz olsalar bile her zaman küme parantezlerini eklerim, çünkü kodu daha okunaklı hale getirir.
Micheal Johnson

Doğru / yanlış cevabınıza, ekleyerek +3 yerine, bunun yerine ==0+2 olabilir <1. :)
Kevin Cruijssen

2

JavaScript (Node.js) , 47 bayt

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

Zaten çok daha kısa bir cevap olsa da, bu benim ilk JavaScript girişimim ve bu yüzden golf önerilerini dinlemek istiyorum :-)

Test yapmak

Alternatif olarak, çevrimiçi deneyebilirsiniz!


2

Perl 5, 37 32 + 1 (-p) bayt

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

Dom Hastings sayesinde -5 bayt. 37 +1 bayt

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

çevrimiçi dene


1
Bununla küçük bir oyun --$|oynadım 1ve faydalı bir numarayı paylaşacağımı düşündüm: aralarında geçiş yapar ve 0böylece ++$i%2alternatif bir boole yerine bunu kullanabilirsiniz ! Ayrıca, tüm mesele şu ki, toplam ( $s) eşleşir /0$/, bu değişiklikleri birleştiren 33 bayt elde etmeyi başarır s///: Çevrimiçi deneyin! ( -lsadece görünürlük için)
Dom Hastings

evet ben için olsa s/./(something with $&)/geve /0$/maç ancak iki birleştirdi.
Nahuel Fouilleul

2

Brainfuck, 228 Bayt

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

Muhtemelen adil bir bit geliştirilebilir. Giriş bir defada 1 hane alınır, doğru çıktı için 1, yanlış yanlış için 0 olur.

Nasıl çalışır:

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

8 konumuna 3 konumuna getirin.

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

Her defasında ascii değerden gerçek +2 değerine değiştirerek girişi 8 kez alır. Girdiler, daha sonra kolayca çarpılmasını sağlamak için kaldırılacak olanlarla ayrılmıştır.

>[->]

Her maddeden bir tane çıkarın. Kasetimiz şimdi bir şeye benziyor

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

Her değerde 1 olması gerekenden daha fazla. Bunun sebebi, sıfırların çarpma sürecimizi bozmasıdır.

Şimdi çarpmaya başlamak için hazırız.

<<<<

En son ikinci öğeye git.

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

Sıfır iken, öğeyi üç ile çarpın, ardından iki öğeyi sola kaydırın. Şimdi ihtiyacımız olan her şeyi üçe katladık ve kasetteki ilk pozisyondayız.

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

Tüm listeyi toplayın.

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

Elimizdeki değer 16 gerçek değerden daha fazla. 16'yı çıkararak bunu düzelt.

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

Toplamın 10 katı olup olmadığını test etmemiz gerekir. Maksimum toplam, 9'luk 9'dur, 144'dür. Toplam 10 * 15'ten büyük olamayacağından, kasette 15 ve 10'u bu sıraya ve sağa koymak toplamın hakkı.

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

15 olduğu yere git. Sıfır olmasa da, toplamın sıfır olmadığını test edin. Eğer öyleyse, ondan 10 çıkarın. Şimdi ya (boş) toplam konumunda ya da (aynı zamanda boş) on konumundayız. Bir tane sağa hareket ettirin. Toplam pozisyonundaysak, şimdi sıfır olmayan 15 pozisyonundayız. Eğer öyleyse, iki kez sağa hareket ettirin. Şimdi her iki durumda da aynı pozisyondayız. On konumuna on ekleyin ve birini 15 konumundan çıkarın.

Gerisi çıktı içindir:

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

Toplam konumuna getirin. Sıfır değilse (negatif), barkod geçersiz; konumunu -1 olarak ayarlayın. Şimdi doğru ascii değerini almak için 49 ekleyin: eğer geçerliyse 1, eğer geçersizse 0.


2

Java 8, 53 bayt

golfed:

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

Lambda'da doğrudan hesaplama en kısa çözüme ulaşır. Tek bir ifadeye uyar, lambda ek yükünü en aza indirir ve değişken değişken bildirimlerini ve noktalı virgülleri kaldırır.

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

Çıktı:

[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 bayt

Ah, sıkıcı cevabın en kısa olduğu ortaya çıktı:

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

Bu, virgülle ayrılmış basamakları girer. Her seferinde bir rakam girilen orijinal 54 baytlık çözümüm "daha güzel" bir yaklaşım kullanıyor:

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 bayt

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

Çevrimiçi deneyin!

Teşekkür

@KevinCruijssen ve exclusive-ya da işlecini kullanan zarif numara sayesinde -3 bayt.

DeGolfed

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 bayt

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

Çevrimiçi deneyin!

@ Snowman'ın cevabının direkt limanı .


İlk cevabınız için: b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}( 62 bayt ) veya alternatif olarak bir foreach ile, ayrıca 62 bayt: b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}( Java 8 cevabımın bir limanıdır ).
Kevin Cruijssen

1

MATLAB / Octave , 32 bayt

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

Çevrimiçi deneyin!

Bu kodu ve yaklaşımı diğer cevaplara bakmadan geliştirdiğim için diğer Octave cevabına rağmen bunu göndereceğim.

Burada girişi 8 değerlik bir dizi olarak alan ve geçerli bir barkod varsa true döndüren adsız bir işleve sahibiz.

Sonuç aşağıdaki gibi hesaplanır.

              2*x(1:2:7)
             [          ,x]
         sum(              )
     mod(                   ,10)
@(x)~
  1. Tek rakam (bir indeksli) 2 ile çarpılır.
  2. Sonuç, toplamı üç kez tek sayıları ve çift rakamları bir kez içerecek bir dizi vererek giriş dizisine hazırlanır.
  3. Verilen sağlama toplamını da içerecek toplamı, toplamımız içinde yaparız.
  4. Ardından modulo 10 gerçekleştirilir. Sağlanan sağlama toplamı geçerliyse, sağlama toplamı değeri de dahil olmak üzere tüm çarpılmış basamakların toplamı 10'un katı olur. Bu nedenle yalnızca geçerli bir barkod 0 döndürür.
  5. Sonuç geçerliyse, doğru bir mantıksal çıktı elde etmek için ters çevrilir.

1

Excel, 37 bayt

Excel'de 8 ayrı hücreye izin verdiğine "8 tamsayının listesi" yorumlanması:

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

= MOD (SUM ((A1: H1) + 2 * (A1 + C1 + E1 + G1)), 10) = 0 Bu formül Excel'de mevcut mu?
RosLuP

@RosLuP, önceden tanımlanmamış, hayır. Ama Modulo, Sum, + etc ;-)
Wernisch 24:17

Sadece şunu söylemek istiyorum ki APL'de ilk önce y = (A1: H1) + 2 * (A1 + C1 + E1 + G1) ve toplam ve moddan sonra işler iyi gidiyor; APL'de iyi sonuç alınmaz, ilk toplam (A1: H1) vb. (1,2,3) + 4 = (5,6,7) ve toplamdan (5,6,7) = 18; Not o şeye toplamı (1,2,3) = 6 ve 18 ila 6 + 4 = 10 farklı Fakat olası Ben makyaj hatası
RosLuP

@RosLuP, Özür dileriz, ()yorumunuzdaki değiştirilenleri özledim .
Wernisch

Sorun Excel'in nasıl yorumladığıdır =(A1:H1): Bu bir dizi olarak ele alınmaz. A-HMenzil içinde olmayan herhangi bir sütuna yerleştirilirse geçersizdir . AH'deki bir sütuna yerleştirilirse, yalnızca o sütunun değerini döndürür. (% Olarak formül:% cinsinden sonuç: C2 -> C1 H999 -> H1 K1 -> # DEĞER!)
Wernisch

1

Ruby, 41 Bayt

Bir dizi tamsayı alır. Jordan sayesinde -6 bayt.

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

Güzel! FWIW mapburada hiç ihtiyacınız yok: zipbir blok atar. $.Başlatmak yerine birkaç bayttan daha fazla tasarruf edebilirsiniz s:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
Ürdün

1

TI-Basic (83 serisi), 18 bayt

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

Girişi liste halinde alır Ans. 1Geçerli barkodlar ve 0geçersiz olanlar için döndürür .

Mathematica cevabımın bir limanı . Çevrimiçi bir test ortamı yerine ekran görüntüsünü içerir:

barkod ekran görüntüsü

Dikkate değer özellik: binomcdf(7,0listeyi oluşturmak için kullanılır {1,1,1,1,1,1,1,1}(başarı olasılığı 0 olan 7 denemeden, N = 0,1, ..., 7 için en fazla N başarısı olacak olasılıkların listesi). Sonra cumSum(bunu şuna dönüştürür {1,2,3,4,5,6,7,8}.

Bu seq(komutun kullanılmasından daha kısa bir bayt olmasına rağmen, tarihsel olarak önemli olan daha hızlı olmasıydı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.