Ne kadar yazmam gerekiyor?


35

Sayıların yazılması, Merhaba programlama dünyaları arasında, genellikle de 1-10 arasındadır.

Çok sayı yazmak istiyorum! Çok, çok sayıda. Ama kaç tane sayı yazmalıyım?

Görev

Bir tamsayı girişi verildiğinde, 0'dan girişe kadar olan tüm tamsayı sayılarını içeren bir dizgede bulunacak basamak sayısını bana verecek bir sayı verin. Olumsuz tanımlayıcı ("-"), tek bir karakter olarak sayılır.

Örnek G / Ç

Girdi: 8
Yazılan: 0,1,2,3,4,5,6,7,8
Çıktı: 9

Giriş: 101
yazılan: 0,1,2,3 ...., 99,100,101
Çıktı: 196

Giriş: 102
yazılan: 0,1,2,3 ...., 100,101,102
çıkış: 199

Girdi -10
Yazılı: 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10
çıktı: 22

Bu bir . En düşük bayt sayısı kazanır!

Yanıtlar:


23

05AB1E , 3 bayt

Kod:

ÝJg

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin!

Açıklama:

Ý     # Range [0 .. input]
 J    # Join into one string
  g   # Get the length of the string


11

Röda , 23 bayt

f x{[#([seq(0,x)]&"")]}

Çevrimiçi deneyin!

Açıklaması:

f x{[#([seq(0,x)]&"")]}
f x{                  } /* Defines function f with parameter x. */
        seq(0,x)        /* Creates a stream of numbers from 0 to x. */
       [        ]       /* Creates an array. */
                 &""    /* Joins with "". */
     #(             )   /* Calculates the length of the resulting string. */
    [                ]  /* Returns the value. */


7

Bash + OS X (BSD) yardımcı programları, 24 22 bayt

2 bayt tasarrufu için @seshoumara teşekkürler.

seq 0 $1|fold -1|wc -l

Test Mac OS X'te çalışır:

$ for n in 8 101 102 -10 -1 0 1; do printf %6d $n; ./digitcount $n; done
     8       9
   101     196
   102     199
   -10      22
    -1       3
     0       1
     1       2

İşte bir GNU versiyonu:

Bash + coreutils, 40 38 bayt

Yine, @seshoumara sayesinde 2 bayt kaydedildi.

(seq $1 0;seq 0 $1)|uniq|fold -1|wc -l

Çevrimiçi deneyin!


@tuskiomi BSD yardımcı programlarını kastettiğim zaman coreutils yazdım - Mac OS X'te negatif girdilerde de çalıştığını test ettim (sıra GNU seq ile aynı değil).
Mitchell Spector

@ DigitalTrauma Güzel GNU çözümü. Devam edin ve isterseniz kendiniz gönderin; Ben bir türevi olarak saymak için çok farklı olduğunu düşünüyorum.
Mitchell Spector,


Saymayı fold -1|wc -lyapmak için nasıl kullanılır ? Daha kısa.
seshoumara

6

Python 2, 83 , 78 64 bayt

en kısa versiyon:

lambda x:sum(map(len,map(str,(range(0,x+cmp(x,.5),cmp(x,.5))))))

@numbermaniac sayesinde bu sürüm 5 bayt kurtardı:

x=input()
print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Çevrimiçi deneyin!

bundan sonra kendi başıma buldum (aynı miktarda bayt):

x=input()
print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Çevrimiçi deneyin!


Sen kullanabilirsiniz map78 byte için ikinci satırda: print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1))))). Sen belki bu bir lambda yaparak daha fazla tasarruf.
numbermaniac

1
@ sayı_maniac bu şekilde benzer bir şey yapabilir miyim?
micsthepick

1
@numbermaniac burada eşdeğerdir:print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))
micsthepick 10:17

lambda x:sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))71 bayt için
Felipe Nardi Batista

6

Java 7, 74 bayt (özyinelemeli - ikinci varsayılan parametre dahil)

int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

Açıklama (1):

int c(int r, int n){     // Recursive method with two integer parameters and integer return-type
                         // Parameter `r` is the previous result of this recursive method (starting at 0)
  r += (n+"").length();  //  Append the result with the current number's width
  return n > 0 ?         //  If the input is positive
     c(r, n-1)           //   Continue recursive method with n-1
    : n < 0 ?            //  Else if the input is negative
     c(r, n+1)           //   Continue recursive method with n+1
    ?                    //  Else (input is zero)
     r;                  //   Return the result
}                        // End of method

Java 7, 81 79 bayt (döngü - tek parametre)

0Bu özyinelemeli yaklaşımla ilgili olarak varsayılan bir ikinci parametreye sahip olmanızın bir nedenden ötürü kabul edilmemesi durumunda, bunun gibi bir for-döngüsü kullanılabilir:

int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

Açıklama (2)

int d(int n){                 // Method with integer parameter and integer return-type
  String r = "x";             //  Initial String (with length 1 so we won't have to +1 in the end)
  for(int i=n; i != 0;        //  Loop as long as the current number isn't 0
      i += n < 0 ? 1 : 1)     //   After every iteration of the loop: go to next number
    r += i;                   //   Append String with current number
                              //  End of loop (implicit / single-line body)
  return r.length();          //  Return the length of the String
}                             // End of method

Test kodu:

Burada dene.

class M{
  static int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

  static int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

  public static void main(String[] a){
    System.out.println(c(0, 8) + "\t" + d(8));
    System.out.println(c(0, 101) + "\t" + d(101));
    System.out.println(c(0, 102) + "\t" + d(102));
    System.out.println(c(0, -10) + "\t" + d(-10));
  }
}

Çıktı:

9   9
196 196
199 199
22  22

1
Bu çözümü beğendim, :)
tuskiomi

4

RProgN 2,5 bayt

n0R.L

explination

n0R   # A Stack of all numbers between 0 and the input converted to a number.
   .L # The length of the stringification of this.

Basit çözüm, bir cazibe gibi çalışır.

Çevrimiçi deneyin!


4

Brachylog , 5 bayt

⟦ṡᵐcl

Çevrimiçi deneyin!

[0, input] aralığını oluşturur, her sayıyı dizeye dönüştürür, tek bir dizeye birleştirir ve sonucun uzunluğunu döndürür


TIO'nun bir argümanı olduğunu fark ettim Z; bunun nesi var? Sayımda mı olmalı?
steenbergh

3
@ steenbergh: Leo'nun sunumu tam bir program değil, bir fonksiyondur. Argümanı ZBrachylog yorumlayıcısına vermek, işlevi test edilebilir hale getirmek için uygun bir sarıcı eklemesini söyler. (Eğer tam bir program olarak çalıştırdıysanız, herhangi bir çıktı üretmez.) Burada ya programın ya da işlev gönderimlerinin yapılmasına izin veriyoruz.

4

PHP, 59 60 bayt

Roberto06 tarafından aşıldı - https://codegolf.stackexchange.com/a/112536/38505

Roberto06 sayesinde önceki sürümün negatif sayılar için işe yaramadığını fark ettiniz.

Basitçe bir sayılar dizisi oluşturur, onu bir dizgeye koyar, sonra rakamları (ve eksi işaretini) sayar.

<?=preg_match_all("/\-|\d/",implode(",",range(0,$argv[1])));

Örnek çalıştır: php -f 112504.php 8


Bu negatif bir girdi için işe yaramaz, buraya bakın
roberto06

Bunun joinyerine implodebir takma ad olduğundan, 3 bayt kullanarak tasarruf edebilirsiniz .
Mario

eksi -1 bayttan kaçmaya gerek yoktur. Diğer taraftan [--9]
regex'inizi

4

Haskell , 39 38 bayt

f 0=1
f n=length$show=<<[0..n]++[n..0]

Çevrimiçi deneyin! Düzenleme: @xnor sayesinde 1 bayt kaydedildi!

Açıklama:

Sayılar için Haskell'de ave b [a..b]aralıktır aiçin bbağlı olarak 1-artışlarla ya da 1-azalmasına bölgesi bdaha büyük olan a. Yani olumlu için nilk listede [0..n]++[n..0]olan [0,1,2,...,n]ve ikincisi ise boş. Negatif niçin ikinci aralık verilir [0,-1,-2,...,n]ve birincisi boştur. Bununla birlikte, n=0her iki aralık da listeyi verirse [0], birleştirme [0,0]yanlış bir sonucuna neden olur 2. Bu yüzden 0özel bir durum olarak ele alınıyor.

=<<Bir listedeki -Operatör aynıdır concatMapher sayı ile bir dizeye dönüştürülür, böylece showve tüm bu dizeleri olan bir uzun dizesinde birleştirilmiş lengthnihayet döndürülür.


Xnor'ın bahşişinden önce [0,signum n..n]onun yerine kullandım [0..n]++[n..0]. signum nbir -1negatif sayılar için 0sıfır ve 1pozitif sayı ve formunun bir aralığı [a,b..c]ile ilgili sayıların listesi oluşturur aiçin cartış ile b. Böylece [0,signum n..n], [0,1,2,...,n]pozitif nve [0,-1,-2,...,n]negatif için aralık oluşturulur n. İçin n=0sonsuz liste kuracağına [0,0,0,...]biz idare etmeye gerek böylece 0özel bir durum olarak da.


Bence [0..n]++[n..0]yapmalıyım [0,signum n..n].
xnor

4

PHP, 41 35 bayt

User59178 sayesinde 6 bayt kaydedildi

Yana ʰᵈ cevabı olumsuz girişi için yanlış olduğunu, yeni bir çözüm oluşturmak için kendime görev edindim:

<?=strlen(join(range(0,$argv[1])));

Bu işlev:

  • Bir dizi oluşturur 0için $argv[1](giriş olarak da bilinir)
  • Boş bir karakterle yerleştirir (yani bir dizeye dönüştürür)
  • Dize uzunluğunu ekolar

Burada dene!


Bu benim için daha güzel bir çözüm, neden bunu yapmak zorunda olduğumu düşündüğüm idk preg_match():(
ʰᵈˑ

Eh, düşünce olmazdı range()senin çözümü için değildi, ben ödeştik galiba;)
Roberto06

1
join()yerine 3 bayt kaydedebilirsiniz implode(). Aynı şey için bir takma addır. php.net/manual/en/function.join.php
user59178 10:17

1
Ve 'tutkal' parametresini ihmal ederek 3 tane daha.
kullanıcı59178,

Bunun bir takma adı olduğunu biliyordum implode, ancak gue parametresini atlayabileceğimi bilmiyordum. Teşekkürler !
roberto06


4

R, 26 20 bayt

sum(nchar(0:scan()))

Çok temel yaklaşım:

  • Bir vektör yap 0: x

  • Her değerdeki karakterleri sayın (otomatik olarak dizgeye zorlanacaktır)

  • toplam

İşlev tanımını azaltmak için herhangi bir püf noktası olup olmadığından emin değil misiniz? Giuseppe yerine 6 bayt, yerine stdin'den girdi alarak tasarruf etti.


sum(nchar(0:scan()))bunun yerine yapıp nstdin'den okuyabilirsiniz .
Giuseppe

4

Mathematica, 48 47 46 bayt

Martin Ender'e -1 bayt !

StringLength[""<>ToString/@Range[0,#,Sign@#]]&

İsimsiz işlev, sayıyı argüman olarak alarak.

Greg Martin tarafından daha kısa çözüm , 39 bayt

1-#~Min~0+Tr@IntegerLength@Range@Abs@#&

1
Sen kullanabilirsiniz Sign@#için #/Abs@#.
Martin Ender

1
Sen biraz daha farklı bir yaklaşımla birkaç byte kaydedebilirsiniz: 1-#~Min~0+Tr@IntegerLength@Range@Abs@#&. Başlangıçta 10 basamağı -#~Min~0, giriş ise negatif ise tüm negatif işaretler için hesap verir.
Greg Martin

3

Toplu iş, 110 bayt

@set/a"n=%1,t=n>>31,n*=t|1,t=1-t*n,i=0
@for /l %%i in (0,1,9)do @set/a"t+=(i-n)*(i-n>>31),i=i*10+9
@echo %t%

Hesaplar sum(min(0,abs(n)+1-10^k),k=0..9)+(n<0?1-n:1). (Yalnızca 9Batch'ın tamsayı aritmetiğindeki sınırlamalar nedeniyle yukarı çıkmam gerekiyor .)


3

Python 2,68 bayt

def f(i,j=1):
 if i==0:print j
 else:j+=len(`i`);f((i-1,i+1)[i<0],j)

Çevrimiçi deneyin!

Diğer Python çözümlerinden daha uzun ancak farklı. Örnek olarak adlandırılan özyinelemeli bir işlev tanımlar.f(10)


3

MATL , 11 bayt

0hSZ}&:VXzn

Çevrimiçi deneyin!

0h           % Implicitly input n. Append a 0: gives array [n 0]
  S          % Sort
   Z}        % Split array: pushes 0, n or n, 0 according to the previous sorting
     &:      % Binary range: from 0 to n or from n to 0
       V     % Convert to string. Inserts spaces between numbers
        Xz   % Remove spaces
          n  % Length of string. Implicit display

3

PowerShell , 23 bayt

-join(0.."$args")|% Le*

Çevrimiçi deneyin! (çok büyük (mutlak) girişler için TIO’ya yaslanacak)

Girdiden girişe ..bir aralık oluşturmak için range operatörünü kullanır (giriş dizisinden dönüştürülecek bir dize olarak kullanılır). Bu bir ipte bir araya getirilir (örneğin, ) ve sonra bunların sayısı alınır. Bu boru hattında bırakılır ve çıktı örtüktür.0$args-join01234Le


Bu soruyu okuduğumda aklımda tam çözüm 😝
briantist


3

QBIC , 25 bayt

:[0,a,sgn(a)|A=A+!b$]?_lA

Açıklama:

:[0,a     Read 'a' from the cmd line, start a FOR loop from 0 to 'a'
,sgn(a)|  with incrementer set to -1 for negative ranges and 1 for positive ones
A=A+!b$   Add a string cast of each iteration (var 'b') to A$
]         NEXT
?_lA      Print the length of A$

3

JavaScript, 50 bayt

@ETHproductions ile İşbirliği Yaptı

n=>{for(t="";n;n<0?n++:n--)t+=n;alert(++t.length)}


3

Retina , 28 bayt

\d+
$*
1
$`1¶
1+
$.&
^-?
0
.

Çevrimiçi deneyin!

açıklama

\d+
$*

Işareti değmemiş tutarak, numarayı birliğe dönüştürün.

1
$`1¶

Her 1 kendi başına her şey artı yeni bir satırla değiştirilir. Bununla n'nin pozitif olması durumunda 1'den n'ye, negatif ise başlangıçta -1'den n'ye kadar bir aralık alırız -. Tüm numaralar tek satırda ve yeni satırlara göre ayrılmış.

1+
$.&

Her birinin dizisini karşılık gelen ondalık sayıya dönüştürün.

^-?
0

0Başlangıçta bir tane koyun , -varsa ekstraları değiştirin .

.

(Newline olmayan) karakter sayısını sayın.


3

Emacs, 20 bayt

C-x ( C-x C-k TAB C-x ) M-{input} C-x e C-x h M-=

Komutun kendisi 20 tuş vuruşudur, ancak bunun bayt olarak nasıl sayılması gerektiğine dair açıklamaya ihtiyacım var. Her bir tuş vuruşunu 1 bayt olarak saymanın en adil olacağını düşündüm. Yukarıdaki komut, daha kolay okumak için geleneksel olarak yazılmıştır.

açıklama

C-x (

Bir klavye makrosu tanımlamaya başlayın.

C-x C-k TAB

Yeni bir makro sayacı oluşturun. Tampona yazar 0; sayacın değeri şimdi 1'dir.

C-x )

Klavye makro tanımını sonlandırın.

M-{input} C-x e

META'ya bastıktan sonra giriş numaranızı girin. C-x eO defalarca makro yürütür.

C-x h

İşareti tamponun başlangıcına ayarla (bu şekilde oluşturulan metnin tamamını seçer).

M-=

Seçilen bölgede karakter sayısını çalıştır. Mini tamponda karakter sayısı yazdırılacaktır.

Örnek

Korkunç vurgulama rengi için özür dilerim. Bu, bu komutu 100 girişi ile kullanma örneğidir. Çıkış, ekranın altındaki mini tampondadır.

100 girişli örnek uygulama


Evet, bir tuşa basmanın bir bayt olduğundan eminim.
NoOneIsHere

@HayırBilgisayarHere Bu konuda iki düşüncem var: 1) Ctrl + karakteri tek bayt olarak gösterilebilir mi? Ve 2) Unicode karakterlerini bir bayt olarak sayan bir sürü cevap görüyorum, ama değiller, bu yüzden belki CodeGolf'un belki de "bayt" tanımı olduğunu düşündüm? Teşekkürler.
cheryllium

Gerçekten bilmiyorum Ama Meta hakkında sorabilirsin .
NoOneIsHere

3

Lua, 52 bayt

t=0;for i=0,io.read()do t=t+#tostring(i)end;print(t)

0 - input'tan bir for döngüsü boyunca yinelenir, tam sayıyı idizeye dönüştürür ve tyazdırmadan önce dizenin uzunluğunu eklert



2

C #, 77 73 bayt

@Kevin Cruijssen sayesinde -4 bayt

Lambda işlevi:

(r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};

Ungolfed ve test durumları ile:

class P
{
    delegate int numbers(int e);
    static void Main()
    {
        numbers n = (r) =>
        {
            var l = ""; 
            for (int i = 0, s = r < 0 ? -1 : 1; i != r + s; i += s)
                l += i; 
            return l.Length;
        };
        System.Console.WriteLine(n(8));
        System.Console.WriteLine(n(101));
        System.Console.WriteLine(n(102));
        System.Console.WriteLine(n(-10));
        System.Console.ReadKey();
    }
}

Birkaç byte tasarruf etmek whileiçin forto değiştirebilirsiniz : (r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};( 73 bytes )
Kevin Cruijssen

@Kevin Cruijssen Haklısın, teşekkürler.
Bay Scapegrace

Büyük olasılıkla bir int sayacı kullanabilir ve bazı baytları kaydetmek için döngünün uzunluğunu ekleyebilirsiniz. Birini derlerseniz 2 bayt kaydetme Func<int, int>işlevini çağırabilirsiniz r=>...(muhtemelen bunu yine de yapabilirsiniz).
TheLethalCoder 10:17

2

JavaScript, 44 bayt

f=(n,i=1)=>n<0?f(-n)-n:n<i?1:n+1-i+f(n,i*10)
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>


2

REXX, 56 bayt

arg n
l=0
do i=0 to n by sign(n)
  l=l+length(i)
  end
say l
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.