Dize İçindeki Sayıların Toplanması-Çıkarılması


14

Bir dizeyi girdi olarak alın ve dizedeki tüm rakamların toplanmasını / çıkarılmasını gerçekleştirin ve sonuç olarak bu işlemlerin toplamını alın.

kurallar

  • Dizedeki rakamlar soldan sağa okunur
  • Bir basamak (n) tekse, sonraki basamakla (n + n1) toplama yapın
  • Bir basamak (n) çiftse, bir sonraki basamakla (n - n1) çıkarma yapın
  • Dizedeki son rakama ulaştıysanız, işlemi dizedeki ilk hane ile yapın
  • Çıktı, elde edilen tüm değerlerin toplamı olacaktır
  • Dizede yalnızca bir basamak varsa işlemi kendisiyle yapın (n + n veya nn)
  • Dizede rakam yoksa çıktı 0 olur

Misal

Input: r5e6o9mm!/3708dvc    
Process: (5+6) + (6-9) + (9+3) + (3+7) + (7+0) + (0-8) + (8-5)
Output: 32

notlar

  • İşlev veya tam program kabul edilir
  • Maksimum giriş uzunluğu, dilinizin bir dize girişi sınırına bağlı olacaktır
  • Karakter girişinde herhangi bir kısıtlama yoktur, ancak yalnızca yarım genişlikli rakamlar çıkışa sayılır
  • En az bayt kazanır

4
Birkaç örnek daha iyi olurdu
dylnan

2
Tek bir rakamla biten bir test senaryosu eklemenizi tavsiye ederim.
Arnauld

3
Önerilen testcase: "", "0","1"
tsh

1
Girdiyi dize yerine bir karakter dizisi olarak alabilir miyiz? (Julia bu ikisi arasında bir ayrım yapar.)
sundar - Monica'yı eski haline

4
@sundar Geçerli fikir birliği , bir dizenin karakter dizisi olarak tanımlanmış olmasıdır. Anladığım kadarıyla, dilinizde yerel bir dize türü olsa bile, karakter dizilerine varsayılan olarak izin verilir .
Arnauld

Yanıtlar:


6

Jöle , 17 15 12 bayt

fØDV€ḂT‘ịƲSḤ

Çevrimiçi deneyin!

Test senaryolarını deneyin.

Program yalnızca tek bir rakamı takip eden rakamları tutar ve toplamın iki katını hesaplar.

fØDV€ḂT‘ịƲSḤ   
f                   Remove anything that isn't...
 ØD                 a digit.
   V€               Cast each digit to an integer
         Ʋ          Monad:
     Ḃ              Parity of each digit.
      T             Indices of truthy elements (odd digits).
       ‘            Increment.
        ị           Index into list of digits.
                    Wraps to beginning and if there are no digits this returns 0.
          S         Sum.
           Ḥ        Double.

3

K (ok) , 47 43 40 31 bayt

Çözüm:

{+/(1_x,*x)*2*2!x^:(x-:48)^!10}

Çevrimiçi deneyin!

Açıklama:

Sayı olmayan (dönüştürürken) dize, modulo 2, 2 ile çarp, 1 döndürülmüş x ile çarp ve her şeyi topla.

{+/(1_x,*x)*2*2!x^:(x-:48)^!10} / solution
{                             } / lambda taking implicit x
                           !10  / range 0..10
                          ^     / except
                   (     )      / do this together
                    x-:48       / subtract 48 from x (type fudging char ascii value -> ints), save back into x
                x^:             / x except right, and save back to x
              2!                / modulo 2
            2*                  / multiply by 2
           *                    / multiply by
   (      )                     / do this together
        *x                      / first element of x
       ,                        / append to
      x                         / x
    1_                          / drop first (ie rotate everything by 1)
 +/                             / sum, add (+) over (/)

Saf çözüm:

Sayı olmayan her şeyi dizeden çıkarın (aynı zamanda dönüştürme yaparken), 2 öğeli sürgülü pencereyi alın, tek veya çift olup olmadığını anlayın, uygun şekilde toplama / çıkarma uygulayın, sonra toplayın.

{+/((-;+)2!x).'2':(1+#x)#x^:(x-:48)^!10}

Çevrimiçi deneyin!

Notlar:

  • Girdiyi filtrelemenin daha akıllı bir yolu nedeniyle @ngn sayesinde -4 bayt
  • Yeniden şekillendirmek yerine sürgülü pencere kullanarak -3 bayt
  • Ngn'in çözümünü taşıyan -9 bayt (saf olmayan yaklaşım)

1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn

Çözümü q / kdb + 'da yazdım ve sonra OK'ye taşındım ... bundan birkaç bayt daha sıkıştırabilir!
streetster

1
Ben ngn / k içinde ayrı bir cevap gönderdim , oradan fikir getirmek için çekinmeyin. Bence oK ​​en kısa olacak, çünkü ayrıştırıcı şu anda çöp - değiştirilmiş atamayı düzgün ayrıştırmıyor. Bu arada, ':"sürgülü pencere" olarak farkında değildi - ilginç.
ngn

K'ye çok aşina görünüyorsunuz. Vektör programlama malzemelerini benzer düşünen insanlarla tartışmak ya da sadece geri kalanımızın tartışmasını izlemek istiyorsanız - bu sohbet odamız var . Şakaların çoğu APL ile ilgili, ancak k ve J de konu üzerine.
ngn



2

Powershell, 80 78 76 bayt

($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s

Retina çözeltisi ile -2 bayt teşekkürler Neil

-2 bayt teşekkürler AdmBorkBork

Test komut dosyası:

$f = {
($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s
}

&$f 'r5e6o9mm!/3708dvc'

açıklama

Her şeyden önce: önceki basamak tekse 2 * n, önceki basamak çiftse 0 ekler.

($d="$args"-split'\D*'-ne'')+ # let $d is array contains digits only, each element is a digit
$d[0]|                        # apend first digit to the end of the array
?{                            # where for each digit
    $p-match'[13579]'         # predicate is 'previous digit is odd' (it is false on the first iteration because $p is null)
    $p=$_                     # let previous digit is current
}|
%{                            # for each digit matched to the predicate
    $s+=2*$_                  # add current digit multiply 2 to $s. 
}
$s                            # return sum

Ekstra, 99 bayt

@Neil'den esinlenilmiştir. Yalnızca 'önceki rakam tek' olan normal ifade eşleşme rakamları. MatchesBir olan otomatik bir değişkendir .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s

1
Gibi bir parens içine taşıyarak |?{$_}için bir bayt -ne''ve başka bir takas kaydedin . $d="$args"-split'\D*'-ne''($d="$args"-split'\D*'-ne'')+$d[0]
AdmBorkBork

2

MATL , 18 17 bayt

t4Y2m)!Ut1YSof)sE

Çevrimiçi deneyin!

(Luis Mendo / Giuseppe / her ikisi için -1 bayt!)

Açıklama:

     % Implicit input
 t   % duplicate input
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc']
 4Y2 % push inbuilt literal, characters '0':'9'
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc' '0123456789']
 m)  % extract only characters from input that belong to '0':'9'
     % stack: ['5693708']
 !U  % transpose and convert each value from string to number
     % stack: [5 6 9 3 7 0 8]
 t   % duplicate that
 1YS % circular shift by 1
     % stack: [[5 6 9 3 7 0 8] [8 5 6 9 3 7 0]]
 o   % parity check - 1 for odd, 0 for even
     % stack: [[5 6 9 3 7 0 8] [0 1 0 1 1 1 0]]
 f   % find non-zero value indices in last array
     % stack: [[5 6 9 3 7 0 8] [2 4 5 6]]
 )   % index at those places in the first array
 s   % sum
 E   % multiply by 2
     % (implicit) convert to string and display

Temel fikir, çift sayıları takip eden sayıların yok sayılabilirken, tek sayıları takip eden sayılar iki katına çıkar - ve nihai sonuç, bu iki katlanmış değerlerin toplamıdır.

Ben düşünmüyordu fparite kontrol sonrasında ogerekli olurdu, ama nedense Matl için kaynaklanabilir 0 yılların ve 1 yılların dizisi görmez oyerine pozisyonlara sayısal endeksleri ve indeks gibi götüren, mantıksal dizi olarak 1ve end.


Bunun !Uyerine kullanabileceğinizi düşünüyorum 48-. Devrik burada herhangi bir zarar vermiyor gibi görünüyor. oçünkü doublegiriş sadece mod(...,2), yani çıkış double. Güzel NaNgiriş hilesi! Eğer bu STDOUT'daki yabancı çıktıyı çözmek istiyorsa, Dennis'in bir fikri vardı ve muhtemelen yakında çözecek
Luis Mendo

!Uyerine48-
Giuseppe

@LuisMendo welp, beni yumruk at!
Giuseppe

@Giuseppe :-D :-D
Luis Mendo

İkinize de teşekkürler, düzenlendi. @LuisMendo Ne zaman omantıklı bir dizi çıktısı verir - yoksa vermez? (İtiraf etmeliyim ki, MATLAB'ın sayısal tip sistemine hiç bakmadım.) Ve evet, NaNgüzel bir sentinel yapmayı düşündüm , çünkü herhangi bir yerde gerçek girdi olması pek mümkün değil, ama çok daha uzun süre gerekmeyeceğini bilmek güzel !
sundar - Monica'yı yeniden

2

K (ngn / k) , 33 bayt

{+/(1_x,*x)*2*2!x:-48+x^x^,/$!10}

Çevrimiçi deneyin!

{ } argümanlı bir işlevdir x

!10 liste mi 0 1 ... 9

$ dizelere dönüştür

,/ concatenate

x^aracı xsağda ne olmaksızın

x^x^xsağdaki ile kesişen anlamına gelir , yani yalnızca rakamlarıx

-48+çıkarma 48ASCII kodu olan"0"

x: atamak x

2! mod 2

2* 2 ile çarpıldı

1_x,*xbir damladır: xarkasından ilki x; yani xbir adım sola döndürülmüş

+/ toplam


2

Japt (v2.0a0), 25 19 bayt

Shaggy sayesinde -6 bayt .

kè\D
íÈ°*2*Y°u}Ué)x

Burada deneyin .

Bu sefer rakamsız çalışıyor! Giriş, karakterlerin bir listesidir.


Japt v2'ye geçiş dahil 19 bayt . xYine de fonksiyondaki diziden memnun değil . Herhangi bir sorunuz varsa bana sohbet edin.
Shaggy

Bekleyin, giriş herhangi bir rakam içermiyorsa bunun işe yaramayacağını fark ettiniz.
Shaggy

Ayrıca, v2.0a0, @Shaggy için kaynak nerede? Depoda bulamıyorum.
LegionMammal978

Bu v1 ve bu v2.
Shaggy

Sohbette kaçırırsanız, bunu sizin için 12 bayta indirdim .
Shaggy

2

05AB1E , 12 9 bayt

Dylnan'ın parite numarası kullanarak saf yöntem üzerinde 1 bayt tasarruf
eder Bay Xcoder sayesinde 3 bayt tasarruf etti

þDÁ€ÉÏSO·

Çevrimiçi deneyin!

açıklama

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double

Hmm, olur þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·veya þÀsþ€ÉÏSO·-2 bayt için tüm test durumları geçmektedir?
Bay Xcoder

@ Mr.Xcoder: Ah, evet. Güzel! þDÁ€ÉÏSO·-3 için bile yapabiliriz :)
Emigna

1

Retina , 37 bayt

(\d).*
$&$1
L$`(?<=[13579]\D*).
2**
_

Çevrimiçi deneyin! Açıklama:

(\d).*
$&$1

İlk basamağın bir kopyasını ekleyin.

L$`(?<=[13579]\D*).

İlk basamağı tuhaf olan her şeyi eşleştirin.

2**

Tüm maçları tekli olarak dönüştürün ve ikiye katlayın. (Rakam olmayanlar sıfır olarak kabul edilir.)

_

Toplamı al. Eşleşme yoksa, bu gerektiği gibi sıfır üretir.

Retina 0.8.2'de yapabileceğim en iyi şey 44 byte idi:

[^\d]

(.).*
$&$1
(?<![13579]).

.
$*
.
..
.

Çevrimiçi deneyin! Açıklama:

[^\d]

Rakam olmayanları silin.

(.).*
$&$1

İlk basamağın bir kopyasını ekleyin.

(?<![13579]).

Tek bir rakamı takip etmeyen rakamları silin.

.
$*

Tekli'ye dönüştür.

.
..

Onları ikiye katla.

.

Toplamı al.


Korkarım son rakam garip değilse sonuç yanlış olur
mazzy

1
@mazzy Son rakamı söylediğinizde, ilk rakamı sonuna kopyaladıktan önce mi sonra mı demek istediniz?
Neil

'sonuna kadar'. 'İlk basamağın bir kopyasını ekle' adımı sonuna mı kopyalanıyor? tamam. güzel. Teşekkürler
mazzy


1

JavaScript (ES6), 56 bayt

Girişi bir karakter dizisi olarak alır.

s=>s.map(c=>1/c?r+=p*(p=c*2&2,n=n||c,c):0,n=p=r=0)|r+p*n

Çevrimiçi deneyin!

Yorumlananlar

s =>                     // given the input array s[]
  s.map(c =>             // for each character c in s[]:
    1 / c ?              //   if c is a digit:
      r +=               //     update r:
        p * (            //       p = either 0 or 2 (always 0 on the 1st iteration)
          p = c * 2 & 2, //       p = 0 if c is even, 2 if c is odd
          n = n || c,    //       if n is still equal to 0 (as an integer), set it to c
          c              //       compute p * c
        )                //     add the result to r
    :                    //   else:
      0,                 //     do nothing
    n = p = r = 0        //   n = first digit, p = previous digit, r = result
  )                      // end of map()
  | r + p * n            // compute the last operation with the 1st digit and add it to r

1

JavaScript (Node.js) , 85 84 83 82 bayt

Ovs sayesinde -1 bayt

s=>(s.match(/\d/g)||[]).reduce((r,n,i,a)=>r+(+n)+a[a[++i]!=null?i:0]*-(1-n%2*2),0)

Çevrimiçi deneyin!

Dize girişini alır, rakamları bir karakter dizisi olarak bulur veya bulunamazsa boş dizi döndürür ve ardından değerlerin doğru bir şekilde eklenmesini / çıkarılmasını sağlamak için tür zorlama kullanır. İleriye doğru arama, endeksi önceden belirler ve kısalık için boş bir denetim kullanır ve daha sonra son bölüm, sayının tek olup olmadığını ve hatta toplama veya çıkarma işlemini zorlamak için (+ ve - - - vb.)


n-0olabilir+n
ovs

PPCG'ye Hoşgeldiniz!
Conor O'Brien

1

R , 58 bayt

function(x,y=strtoi(x[x%in%0:9]))sum(c(y[-1],y[1])*y%%2*2)

Çevrimiçi deneyin!


Çıktıya aldırmazsanız 67 baytarray .
Giuseppe

1
hmm aslında nokta dizi boş dizisi nedeniyle kullanamazsınız, xxxbu nedenle oluşturmak aiçin dizinleme değişikliği kullanarak 68 bayt y.
Giuseppe

@Giuseppe: değiştirildi, teşekkürler :)
digEmAll

@Giuseppe: Daha akıllı bir kod-golfçüsü olduğunuz için size fikrinizi soruyorum ... yorumlardan bir karakter vektörü kullanabileceğimiz anlaşılıyor, bu durumda 61 bayt mümkündür: Çevrimiçi deneyin! ne düşünüyorsun ?
digEmAll

strtoiyerine kullanın as.double, ama evet, bu iyi olmalı.
Giuseppe



0

C Keskin 180 bayt

Bu çok iyi golf değil, lol.

s=>{var q=new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));q.Enqueue(q.First());int t,o=0;o=q.Dequeue();try{while(true){t+=o+(o%2==0?-1:1)*(o=q.Dequeue());}}catch{return t;}}

Kurtulmamış:

var q = new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));
int t,o=0;

q.Enqueue(q.First());    
o=q.Dequeue();

try{
    while(true){
        t += o + (o%2==0?-1:1) * (o=q.Dequeue());
    }
}
catch {
    return t;
}

0

Stax , 14 bayt

ÿ←«4é■≥B▬ê→█T♥

Çalıştır ve hata ayıkla

Ambalajından çıkarılmış, golf edilmemiş ve yorum yapılmış gibi görünüyor.

Vd|&    filter out non-digits
c|(\    zip into pairs after rotating right
F       for each digit pair
  B2%s  first-of-pair % 2, then swap top two stack elements
  eH*   eval digit as integer, double, then multiply
  +     add to running total

Bunu çalıştır


0

JavaScript (ES6), 52 bayt

s=>s.filter(t=>1/t&&~(a+=u*t,u=t%2),a=u=0)[0]*u+a<<1

Girişi bir karakter dizisi olarak bekler. Uyarı: Bit kaydırma kullanımı nedeniyle, çıkışın üst sınırı vardır.2^31-1

Çevrimiçi deneyin!

açıklama

Aslında tek değerleri izleyen basamakların toplamını iki katına çıkarır.

s => s.filter(             // filter to preserve the first digit
    t =>
        1/t &&             // short-circuits if NaN
        ~(                 // coerce to truthy value
            a += u * t,    // adds value only if previous digit is odd
            u = t%2        // store parity of current digit
        ),
    a = u = 0
)[0]                       // first digit
* u + a
<< 1                       // bit-shift to multiply by 2 (also coerces a NaN resulting from a string devoid of digits to 0)
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.