ฉันต้องเขียนเท่าไหร่


35

การเขียนตัวเลขเป็นส่วนหนึ่งของโลกแห่งการเขียนโปรแกรมสวัสดีซึ่งมักจะเป็นตัวเลข 1-10

ฉันต้องการเขียนตัวเลขจำนวนมาก! จำนวนมากจำนวนมาก แต่ฉันต้องเขียนตัวเลขกี่ตัว?

งาน

กำหนดอินพุตจำนวนเต็มให้ตัวเลขเป็นเอาท์พุทที่จะให้ฉันจำนวนหลักที่จะอยู่ในสตริงที่มีตัวเลขจำนวนเต็มทั้งหมดในช่วงจาก 0 ถึงอินพุตรวม ตัวระบุการปฏิเสธ ("-") นับเป็นอักขระเดียว

ตัวอย่าง I / Os

อินพุต: 8
เขียนออก: 0,1,2,3,4,5,6,7,8
เอาต์พุต: 9

ป้อนข้อมูล: 101
เขียนออก: 0,1,2,3 .... , 99,100,101
เอาท์พุท: 196

อินพุต: 102
เขียนออก: 0,1,2,3 .... , 100,101,102
ผลลัพธ์: 199

อินพุต -10
เขียนออก: 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -9, -10
เอาต์พุต: 22

นี่คือรหัสกอล์ฟจำนวนไบต์ต่ำสุดชนะ!

คำตอบ:




11

Röda , 23 ไบต์

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

ลองออนไลน์!

อธิบาย:

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), 24 22 ไบต์

ขอบคุณ @seshoumara สำหรับการบันทึก 2 ไบต์

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

ทดสอบทำงานบน Mac OS X:

$ 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

นี่คือรุ่น GNU:

Bash + coreutils, 40 38 ไบต์

อีกครั้ง 2 ไบต์ช่วยขอบคุณ @seshoumara

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

ลองออนไลน์!


@tuskiomi ฉันเขียน coreutils เมื่อฉันหมายถึงอรรถประโยชน์ของ BSD - ฉันทดสอบใน Mac OS X ซึ่งทำงานกับอินพุตเชิงลบด้วย (seq ไม่มีเหมือนกับ GNU seq)
Mitchell Spector

@DigitalTrauma Nice GNU ทางออก ไปข้างหน้าและโพสต์ด้วยตัวคุณเองถ้าคุณต้องการ; ฉันคิดว่ามันแตกต่างกันเกินกว่าที่จะนับว่าแตกต่างจากของฉัน
Mitchell Spector


วิธีใช้เกี่ยวกับfold -1|wc -lการนับ มันสั้นกว่า
seshoumara

6

Python 2, 83 , 78 64 ไบต์

รุ่นที่สั้นที่สุด:

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

รุ่นนี้บันทึก 5 ไบต์ด้วย @numbermaniac:

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

ลองออนไลน์!

หนึ่งนี้ฉันมาด้วยตัวเองหลังจากนั้น (จำนวนไบต์เดียวกัน):

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

ลองออนไลน์!


คุณสามารถใช้mapในบรรทัดที่สอง 78 print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))ไบต์: คุณอาจประหยัดได้มากขึ้นด้วยการทำให้เป็นแลมบ์ดา
numbermaniac

1
@numbermaniac ฉันสามารถทำอะไรที่คล้ายกันได้ไหม
micsthepick

1
@ จำนวนช่างที่นี่เทียบเท่า:print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))
micsthepick

lambda x:sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))for 71 bytes
Felipe Nardi Batista

6

Java 7, 74 ไบต์(เรียกซ้ำ - รวมถึงพารามิเตอร์เริ่มต้นที่สอง)

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

คำอธิบาย (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 ไบต์(ลูป - พารามิเตอร์เดียว)

หากมีพารามิเตอร์ที่สองที่เป็นค่าเริ่มต้น0สำหรับวิธีแบบเรียกซ้ำนี้ไม่ได้รับอนุญาตด้วยเหตุผลบางประการสามารถใช้ for-loop แบบนี้แทน:

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

คำอธิบาย (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

รหัสทดสอบ:

ลองที่นี่

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

เอาท์พุท:

9   9
196 196
199 199
22  22

1
ฉันชอบโซลูชันนี้ :)
tuskiomi


4

Brachylogขนาด 5 ไบต์

⟦ṡᵐcl

ลองออนไลน์!

สร้างช่วง [0, อินพุต], แปลงตัวเลขแต่ละตัวเป็นสตริงเชื่อมต่อกันเป็นสตริงเดียวและส่งคืนความยาวของผลลัพธ์


ผมสังเกตเห็น TIO มีการโต้แย้งZ; เกิดอะไรขึ้นกับสิ่งนั้น มันควรจะอยู่ในการนับหรือไม่
steenbergh

3
@steenbergh: การส่งของ Leo เป็นฟังก์ชั่นไม่ใช่โปรแกรมเต็มรูปแบบ การให้อาร์กิวเมนต์Zกับล่าม Brachylog บอกให้เพิ่ม wrapper ที่เหมาะสมเพื่อให้ฟังก์ชันทดสอบได้ (หากคุณเรียกใช้เป็นโปรแกรมเต็มรูปแบบจะไม่สร้างผลลัพธ์ใด ๆ ) เราอนุญาตให้ส่งโปรแกรมหรือฟังก์ชั่นที่นี่ดังนั้นจึงไม่ควรนับรวมกับจำนวนไบต์เนื่องจากไม่ใช่ส่วนหนึ่งของการส่งจริง

4

PHP, 59 60 ไบต์

Outgolfed โดย Roberto06 - https://codegolf.stackexchange.com/a/112536/38505

ขอบคุณroberto06สำหรับการสังเกตรุ่นก่อนหน้านี้ใช้ไม่ได้กับจำนวนลบ

เพียงสร้างอาร์เรย์ของตัวเลขวางลงในสตริงจากนั้นนับตัวเลข (และเครื่องหมายลบ)

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

เรียกใช้ตัวอย่าง: php -f 112504.php 8


วิธีนี้ใช้ไม่ได้กับอินพุตเชิงลบให้ดูที่นี่
roberto06

คุณสามารถบันทึกได้ 3 ไบต์โดยใช้joinแทนimplodeเพราะเป็นชื่อแทน
มาริโอ

ไม่จำเป็นต้องหลบหนีลบ -1 ไบต์ ในทางกลับกันคุณสามารถเปลี่ยน regex ของคุณเป็น[--9]
JörgHülsermann

4

Haskell , 39 38 ไบต์

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

ลองออนไลน์! แก้ไข: บันทึกแล้ว 1 ไบต์ขอบคุณ @xnor!

คำอธิบาย:

ใน Haskell สำหรับตัวเลขaและb [a..b]เป็นช่วงจากaถึงb1 ครั้งหรือเพิ่มขึ้น 1 ครั้งทั้งนี้ขึ้นอยู่กับว่าbมีขนาดใหญ่กว่าaหรือไม่ ดังนั้นในเชิงบวกnรายการแรก[0..n]++[n..0]คือ[0,1,2,...,n]และรายการที่สองว่างเปล่า สำหรับผลลบnช่วงที่สองให้ผลตอบแทน[0,-1,-2,...,n]และช่วงแรกว่างเปล่า แต่ถ้าn=0ทั้งสองช่วงผลผลิตรายการ[0]เพื่อให้การ concatenation จะนำไปสู่ผลที่ผิดพลาดของ[0,0] 2นั่นเป็นเหตุผลที่0ถูกจัดการเป็นกรณีพิเศษ

=<<-operator ในรายการเป็นเช่นเดียวกับconcatMapเพื่อให้แต่ละหมายเลขจะถูกแปลงเป็นสตริงโดยshowและสตริงทั้งหมดเหล่านั้นจะถูกตัดแบ่งในสายยาวหนึ่งที่lengthจะถูกส่งกลับในที่สุด


ก่อนที่ปลาย XNOR ของผมใช้แทน [0,signum n..n] เป็นตัวเลขเชิงลบสำหรับศูนย์และสำหรับตัวเลขในเชิงบวกและช่วงของรูปแบบการสร้างรายการของตัวเลขจากการที่มีเพิ่มขึ้น จึงสร้างช่วงบวกและเชิงลบ เพราะมันจะสร้างรายการที่ไม่มีที่สิ้นสุดดังนั้นเราจึงต้องจัดการเป็นกรณีพิเศษด้วย[0..n]++[n..0]signum n-101[a,b..c]acb[0,signum n..n][0,1,2,...,n]n[0,-1,-2,...,n]nn=0[0,0,0,...]0


ผมคิดว่าควรจะทำอย่างไรสำหรับ[0..n]++[n..0] [0,signum n..n]
xnor

4

PHP, 41 35 ไบต์

บันทึกแล้ว 6 ไบต์ขอบคุณ user59178

เนื่องจากคำตอบของʰᵈผิดสำหรับการป้อนข้อมูลเชิงลบฉันจึงตัดสินใจสร้างโซลูชันใหม่:

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

ฟังก์ชั่นนี้:

  • สร้างอาร์เรย์จาก0ถึง$argv[1](aka อินพุต)
  • แปลงมันด้วยอักขระว่าง (เช่นแปลงเป็นสตริง)
  • สะท้อนความยาวของสตริง

ลองที่นี่!


นี่เป็นทางออกที่ดีกว่าสำหรับฉัน idk ทำไมฉันคิดว่าฉันต้องทำอย่างนั้นpreg_match():(
ʰᵈˑ

ดีฉันจะไม่คิดว่าrange()ถ้ามันไม่ได้สำหรับการแก้ปัญหาของคุณฉันเดาว่าเราจะได้;)
roberto06

1
คุณสามารถบันทึก 3 ไบต์โดยใช้แทนjoin() implode()มันเป็นนามแฝงสำหรับสิ่งเดียวกัน php.net/manual/en/function.join.php
user59178

1
และอีก 3 รายการโดยละเว้นพารามิเตอร์ 'กาว'
user59178

ฉันรู้ว่ามีนามแฝงอยู่implodeแต่ฉันไม่รู้ว่าฉันสามารถละเว้นพารามิเตอร์ gue ได้ ขอบคุณมาก!
roberto06


4

R, 26 20 ไบต์

sum(nchar(0:scan()))

วิธีการพื้นฐานมาก:

  • ทำเวกเตอร์ 0: x

  • นับจำนวนตัวอักษรในแต่ละค่า (จะถูกรวมเข้ากับสตริงโดยอัตโนมัติ)

  • รวม

ไม่แน่ใจว่ามีกลอุบายใดที่จะลดความหมายของฟังก์ชั่นหรือไม่? บันทึกไปแล้ว 6 ไบต์ด้วย Giuseppe โดยรับอินพุตจาก stdin แทน


คุณสามารถทำsum(nchar(0:scan()))แทนและอ่านnจาก stdin แทน
Giuseppe

4

Mathematica, 48 47 46 ไบต์

-1 ไบต์ขอบคุณMartin Ender !

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

ฟังก์ชั่นไม่ระบุชื่อโดยใช้ตัวเลขเป็นอาร์กิวเมนต์

โซลูชันที่สั้นลงโดยGreg Martinขนาด 39 ไบต์

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

1
คุณสามารถใช้สำหรับSign@# #/Abs@#
Martin Ender

1
คุณสามารถบันทึกสองสามไบต์ด้วยวิธีที่ต่างกันเล็กน้อย: 1-#~Min~0+Tr@IntegerLength@Range@Abs@#&. 1บัญชีเริ่มต้นสำหรับตัวเลข 0 ในขณะที่-#~Min~0บัญชีสำหรับสัญญาณเชิงลบทั้งหมดหากการป้อนข้อมูลเป็นลบ
Greg Martin

3

แบตช์ 110 ไบต์

@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%

sum(min(0,abs(n)+1-10^k),k=0..9)+(n<0?1-n:1)คำนวณ (ฉันต้องขึ้นไป9เพราะข้อ จำกัด ของเลขจำนวนเต็มของแบทช์)




3

PowerShellขนาด 23 ไบต์

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

ลองออนไลน์! (จะ barf บน TIO สำหรับอินพุต (สัมบูรณ์) ที่มีขนาดใหญ่มาก)

ใช้..โอเปอเรเตอร์ช่วงเพื่อสร้างช่วงจาก0ถึงอินพุต$args(ทอดเป็นสตริงเพื่อแปลงจากอาร์เรย์อินพุต) มันถูก-joinรวมเข้าด้วยกันเป็นสตริง (เช่น01234) จากนั้นLength จะถูกนำมาใช้ ที่เหลืออยู่บนไปป์ไลน์และเอาท์พุทเป็นนัย


คำตอบที่ถูกต้องที่ฉันมีในหัวของฉันเมื่อฉันอ่านคำถามนี้😝
ต้มตุ๋น


3

Qbicขนาด 25 ไบต์

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

คำอธิบาย:

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

เรติน่า 28 ไบต์

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

ลองออนไลน์!

คำอธิบาย

\d+
$*

แปลงหมายเลขเป็นเอกภาพทำให้ไม่มีการแตะเครื่องหมาย

1
$`1¶

แต่ละ 1 จะถูกแทนที่ด้วยทุกสิ่งขึ้นอยู่กับตัวเองบวกกับการขึ้นบรรทัดใหม่ ด้วยสิ่งนี้เราจะได้รับช่วงจาก 1 ถึง n ถ้า n เป็นบวกจาก -1 ถึง n โดยมีค่าเพิ่ม-เมื่อเริ่มต้นถ้ามันเป็นลบ ตัวเลขทั้งหมดอยู่ในช่วงเดียวกันและแยกจากกันโดยการขึ้นบรรทัดใหม่

1+
$.&

แปลงแต่ละลำดับของคนที่เป็นเลขทศนิยมที่สอดคล้องกัน

^-?
0

วาง0ที่จุดเริ่มต้นแทนที่พิเศษ-ถ้ามันมี

.

นับจำนวนอักขระ (ไม่ใช่บรรทัดใหม่)


3

Emacs ขนาด 20 ไบต์

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

คำสั่งนั้นมีการกดแป้น 20 ครั้ง แต่ฉันต้องการคำชี้แจงเกี่ยวกับวิธีการนับจำนวนไบต์ ฉันให้เหตุผลว่าการนับการกดแป้นแต่ละครั้งเป็น 1 ไบต์จะยุติธรรมที่สุด คำสั่งด้านบนเขียนตามอัตภาพเพื่อให้อ่านง่ายขึ้น

คำอธิบาย

C-x (

เริ่มต้นกำหนดแมโครแป้นพิมพ์

C-x C-k TAB

สร้างตัวนับแมโครใหม่ เขียน0ลงในบัฟเฟอร์ ค่าของตัวนับคือ 1

C-x )

สิ้นสุดนิยามแมโครของคีย์บอร์ด

M-{input} C-x e

หลังจากกดปุ่ม META แล้วให้พิมพ์หมายเลขอินพุตของคุณ C-x eแล้วรันแมโครที่หลายต่อหลายครั้ง

C-x h

ตั้งเครื่องหมายเป็นจุดเริ่มต้นของบัฟเฟอร์ (ซึ่งเลือกข้อความทั้งหมดที่สร้างขึ้น)

M-=

เรียกใช้ตัวละครนับในภูมิภาคที่เลือก จำนวนตัวอักษรจะถูกพิมพ์ใน minibuffer

ตัวอย่าง

ขอโทษสำหรับสีไฮไลต์ที่แย่มาก นี่คือตัวอย่างของการใช้คำสั่งนี้กับอินพุต 100 เอาต์พุตอยู่ใน minibuffer ที่ด้านล่างของหน้าจอ

ตัวอย่างการดำเนินการกับอินพุต 100


ใช่ฉันค่อนข้างมั่นใจว่าการกดแป้นหนึ่งครั้งเป็นหนึ่งไบต์
NoOneIsHere

@NoOneIsHere มีสองความคิดที่ฉันมีเกี่ยวกับเรื่องนี้: 1) สามารถ Ctrl + อักขระสามารถแสดงเป็นไบต์เดียวได้หรือไม่ และ 2) ฉันเห็นคำตอบมากมายที่นี่นับจำนวนตัวอักษร Unicode เป็นหนึ่งไบต์ แต่ไม่ใช่ดังนั้นฉันคิดว่า CodeGolf อาจมีคำจำกัดความของตัวเองว่า "byte" ขอบคุณ
cheryllium

ฉันไม่รู้จริงๆ แต่คุณสามารถถามMetaได้
NoOneIsHere

3

Lua ขนาด 52 ไบต์

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

วนซ้ำผ่านลูป for จาก 0 - อินพุตแปลงจำนวนเต็มiเป็นสตริงและเพิ่มความยาวของสตริงtก่อนพิมพ์t



2

C #, 77 73 ไบต์

-4 ไบต์ขอบคุณ @Kevin Cruijssen

ฟังก์ชั่นแลมบ์ดา:

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

Ungolfed และกรณีทดสอบ:

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

คุณสามารถเปลี่ยนwhileเพื่อforที่จะบันทึกคู่ของไบต์: (r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};( 73 ไบต์ )
เควิน Cruijssen

@ Kevin Cruijssen คุณพูดถูกต้องขอบคุณ
Mr Scapegrace

คุณสามารถใช้ตัวนับ int และเพิ่มความยาวภายในลูปเพื่อบันทึกไบต์ หากคุณคอมไพล์ไปยัง a Func<int, int>คุณสามารถเรียกใช้ฟังก์ชันที่ต้องการr=>...บันทึก 2 ไบต์ (อาจทำสิ่งนี้ได้)
TheLethalCoder


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.