นับจำนวนครั้งของจำนวนเต็ม [ปิด]


13

ตามคำถามจำนวนเต็มบวก <1,000,000 ประกอบด้วย 2 หลัก . ฉันกำลังมองหาทางออกที่สร้างสรรค์มากที่สุดจะนับทุกจำนวนเต็มจากXการที่มีจำนวนเต็ม Y สามารถจาก 0 ถึงZZY

จำนวนเต็มที่พบทุกคนจะนับเพียงครั้งเดียวแม้ว่าจำนวนเต็มZจะปรากฏบ่อยขึ้น ตัวอย่างเช่น:

Z = 2
123 counts 1
22222 also counts 1

ฉันจะเริ่มต้นด้วยอัลกอริทึมที่เรียบง่ายจริงๆเขียนใน Java (เพราะทุกคนเป็นที่รัก):

public class Count {
    public static void main(String[] args) {
        int count = 0;
        for (int i = Integer.parseInt(args[0]); i <= Integer.parseInt(args[1]); i++) {
            if (Integer.toString(i).contains(args[2])) {
                count++;
            }
        }
        System.out.println(count);
    }
}

ถ้าคุณทำสิ่งนี้ด้วย

java -jar Count.jar 0 1000000 2

คุณได้รับสิ่งนี้เป็นผล:

468559

เพราะปัญหานี้ไม่ยากที่จะแก้มันเป็นเพียงความนิยมประกวดคำตอบที่โหวตมากที่สุดโพสต์โดย 28 กุมภาพันธ์ชนะ!


ไม่ชัดเจนจากโพสต์ของคุณทั้งหมด แต่ฉันเดาว่า Z สามารถอยู่ระหว่าง 0 ถึง inf? หรือเพียงแค่ระหว่าง 0 ถึง 9
mmumboss

Z สามารถอยู่ระหว่าง 0 ถึง Y ไม่สมเหตุสมผลที่ Z สามารถใหญ่กว่า Y ได้
Obl Tobl

@OblTobl คุณต้องการแยกเคส Z> Y จริงๆหรือไม่ ทำไมไม่เพียงแค่มีเอาท์พุทที่คาดว่าจะเป็น 0
Cruncher

@Cruncher ฉันไม่สนใจ! แต่มันก็นิด ๆ หน่อย ๆ ผมคิดว่าไร้ประโยชน์ ;-)
OBL Tobl

นี่หมายความว่าNสามารถเป็นได้123และมันจะจับคู่ก็ต่อเมื่อมีสตริงย่อย 123 อยู่หรือไม่
Populus

คำตอบ:



11

funciton

ตามปกติเนื่องจากความสูงของบรรทัดที่เพิ่มโดย StackExchange แยกบรรทัดให้พิจารณาใช้$('pre').css('line-height',1)ในคอนโซลเบราว์เซอร์ของคุณเพื่อแก้ไข

ต่างจากคำตอบ Funciton อื่น ๆ ของฉันอันนี้ไม่ได้ใช้การประกาศฟังก์ชั่นใด ๆ มันเป็นเพียงโปรแกรม มันใช้การแสดงออกแลมบ์ดา - คุณลักษณะที่ฉันเพิ่มใน Funciton ในเดือนธันวาคม :)

คาดว่าอินพุตเป็นเลขทศนิยมสามตัว (อาจเป็นค่าลบ) คั่นด้วยช่องว่าง (เช่นx y z) ในความเป็นจริงzสามารถเป็นสตริงใด ๆ ตัวอย่างเช่นอาจเป็นเพียงเครื่องหมายลบ ( , U + 2212) เพื่อนับจำนวนของจำนวนลบในช่วงเวลา :)

           ┌───╖
     ┌───┬─┤ ♯ ╟──────────┐
     │   │ ╘═══╝ ╔════╗ ┌─┴─╖             ┌────╖ ╔═══╗
   ┌─┴─╖ └────┐  ║ 21 ║ │ × ╟─────────────┤ >> ╟─╢   ║
 ┌─┤ ʃ ╟───┐  │  ╚══╤═╝ ╘═╤═╝             ╘═╤══╝ ╚═══╝
 │ ╘═╤═╝   │  └──┐  └─────┘   ┌───────────┐ │
 │ ╔═╧═╗ ┌─┴─╖ ┌─┴─╖ ╔════╗ ┌─┴─╖   ┌───╖ ├─┴────────┐
 │ ║   ╟─┤ · ╟─┤ ʘ ╟─╢ 32 ╟─┤ · ╟───┤ ʘ ╟─┘          │
 │ ╚═══╝ ╘═╤═╝ ╘═══╝ ╚════╝ ╘═╤═╝   ╘═╤═╝ ┌─────┐    │
 │         └───────┐  ╔═══╗ ┌─┴─╖     │ ┌─┴─╖   │    │
 │ ┌───────────┐   └──╢ 0 ╟─┤ ʃ ╟─┐   │ │ ♯ ║   │    │
 │ │   ┌───╖ ┌─┴─╖    ╚═══╝ ╘═╤═╝ │   │ ╘═╤═╝ ┌─┴─╖  │
 │ │ ┌─┤ ♯ ╟─┤   ╟─┬─┐ ╔════╗ │ ┌─┴─╖ │   │ ┌─┤ × ║  │
 │ │ │ ╘═══╝ └─┬─╜ └─┘ ║ −1 ║ └─┤ · ╟─┴───┘ │ ╘═╤═╝  │
 │ │ │    ┌────┴────┐  ╚══╤═╝   ╘═╤═╝       │ ╔═╧══╗ │
 │ │ │    │ ┌───╖ ┌─┴─╖ ┌─┴─╖ ┌───┴─────╖   │ ║ 21 ║ │
 │ │ │    └─┤ ♯ ╟─┤ ? ╟─┤ = ║ │ str→int ║   │ ╚════╝ │
 │ │ │      ╘═══╝ ╘═╤═╝ ╘═╤═╝ ╘═╤═══════╝   │ ┌────╖ │
 │ │ │      ╔═══╗ ┌─┴─╖   └─┐ ┌─┴─╖         └─┤ >> ╟─┘
 │ │ │      ║ 0 ╟─┤ ? ╟─┐   └─┤ · ╟───┐       ╘═╤══╝
 │ │ │      ╚═══╝ ╘═╤═╝ └─┐   ╘═╤═╝   └───┐   ┌─┴─╖
 │ │ │            ┌─┴─╖   └─┐ ┌─┴─╖       └───┤ ʘ ║
 │ │ └────────────┤ · ╟─┐   └─┤ ≤ ║           ╘═╤═╝
 │ │              ╘═╤═╝ │     ╘═╤═╝ ┌─────────╖ │
 │ │        ╔═══╗ ╔═╧═╕ │       └─┬─┤ int→str ╟─┘
 │ │        ║ 0 ╟─╢   ├─┤         │ ╘═════════╝
 │ │        ╚═══╝ ╚═╤═╛ └─────────┘
 │ └────────────────┴─┐              │
 │    ┌─────────╖   ┌─┴─╖ ┌─┐   ┌────┴────╖
 └────┤ str→int ╟───┤   ╟─┴─┘   │ int→str ║
      ╘═════════╝   └─┬─╜       ╘════╤════╝
                      └──────────────┘

1
มันเจ๋งมาก! ใช้ภาษาที่คุณสร้างขึ้นเอง
pcnThird

2
@ pcnThird: ฉันคิดว่า Timwi ใช้เวลาตลอดเวลาของเขาทั้งการเล่นกอล์ฟหรือการสร้างภาษาในการเล่นกอล์ฟ (ดู Sclipting)!
Gabe

10

ค#

public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine(Enumerable.Range(Convert.ToInt32(args[0]), (Convert.ToInt32(args[1]) + 1) - Convert.ToInt32(args[0])).Count(x => x.ToString().Contains(args[2])));
    }
}

ตัวอย่าง

count.exe 0 1000000 2
468559

ทางออกที่ฉลาด! ฉันชอบที่คุณทำโดยไม่ต้องห่วง
Oblique Tobl

@OblTobl โดยไม่ต้องวนซ้ำที่มองเห็นได้
Justin

แน่นอน anyways ดี
Obl Tobl

1
แต่ก็มีข้อผิดพลาด.Rangeยอมรับไม่ได้(int start, int count) (start, end)ฉันมักจะตกหลุมพรางนี้ด้วยตัวเอง :)
Grozz

ทำหน้าที่ให้ฉันถูกต้องในการเคาะอย่างรวดเร็วใน Notepad ... ฉันปรับแต่งโค้ดดังนั้นตอนนี้มันถูกต้อง!
Mo D

5

APL (29)

{+/∨/¨(⍕⍺)∘⍷¨⍕¨⊃{⍺+0,⍳⍵-⍺}/⍵}

นี่คือฟังก์ชันที่ใช้Zเป็นอาร์กิวเมนต์ซ้ายและช่วงเวลา[X,Y]เป็นอาร์กิวเมนต์ที่ถูกต้อง:

      2 {+/∨/¨(⍕⍺)∘⍷¨⍕¨⊃{⍺+0,⍳⍵-⍺}/⍵} 0 1e6
468559
      0 {+/∨/¨(⍕⍺)∘⍷¨⍕¨⊃{⍺+0,⍳⍵-⍺}/⍵} 0 1e6
402131
      42 {+/∨/¨(⍕⍺)∘⍷¨⍕¨⊃{⍺+0,⍳⍵-⍺}/⍵} 0 1e6
49401

ไม่ชัดเจนจริงๆ ... แต่เจ๋งจริงๆ!
Oblique Tobl

4

Python 2.7

ต้องการความเร็ว

คำอธิบาย

ป้อนคำอธิบายรูปภาพที่นี่

การดำเนินงาน

def Count(lo,hi,key):
    if hi == 0: return 0
    # Count(lo,hi,key) = Count(0,hi,key) - Count(0,lo - 1,key)
    if lo != 0: return Count(0, hi, key) - Count(0, lo - 1, key)
    # Calculate no of digits in the number to search
    # LOG10(hi) may be a descent trick but because of float approximation
    # this would not be reliable
    n = len(str(hi)) - 1
    # find the most significant digit
    a_n = hi/10**n
    if a_n < key:
        count = a_n*(10**n - 9**n)
    elif a_n > key:
        count = (a_n - 1)*(10**n - 9**n) + 10**n
    else:
        count = a_n*(10**n - 9**n) + 1
    if hi % 10**n != 0:
        if a_n != key:
            return count + Count(0, hi%10**n, key)
        else:
            return count + hi%10**n
    else:
        return count

การสาธิต

In [2]: %timeit Count(0,123456789987654321,2)
100000 loops, best of 3: 13.2 us per loop

การเปรียบเทียบ

@Dennis

$ \time -f%e bash count.sh 0 1234567 2
585029
11.45

@arshajii

In [6]: %timeit count(0,1234567,2)
1 loops, best of 3: 550 ms per loop

แน่นอนว่าเร็วกว่านี้มาก แต่ไม่ตอบสนองความต้องการของคำถาม keyสามารถใด ๆจำนวนเต็มไม่หลักระหว่างและlo hi
เดนนิส

ยังคงมีวิธีการแก้ปัญหาทางคณิตศาสตร์แม้ว่ามันจะนานขึ้น ...
Red Alert

3

Python 2.7

โซลูชันที่ใช้นิพจน์ทั่วไป:

>>> from re import findall as f
>>> count=lambda x,y,z:len(f('\d*%d\d*'%z,str(range(x,y+1))))
>>>
>>> count(0,1000000,2)
468559

คุณสามารถใช้งานre.findallในสายการบินเดียวโดยทำ__import__('re').findall('\d...
SimonT

3

ทุบตี - 32 วันที่ 31 17 14 ตัวอักษร + ความยาว X, Y และ Z

ขอบคุณ devnull สำหรับการแนะนำseq!

seq [X] [Y]|grep -c [Z]

เช่น X = 100, Y = 200, Z = 20

$ seq 100 200|grep -c 20
2

เช่น X = 100, Y = 200, Z = 10

$ seq 100 200|grep -c 10
11

เช่น X = 0, Y = 1000000, Z = 2

$ seq 0 1000000|grep -c 2
468559

หนึ่งที่ดีและชัดเจน!
Oblique Tobl

ทำไมต้องใช้echoเมื่อคุณสามารถใช้seqและลดความยาวได้ 4 ตัวอักษร? (1 สำหรับความยาวของคำสั่งที่ 2 สำหรับความสามารถที่จะละเว้นวงเล็บปีกกาและ 1 สำหรับการเปลี่ยน..ที่มีพื้นที่เพียงครั้งเดียว)
devnull

@devnull - ขอบคุณและยังสามารถกำจัดxargsและwc- และมันก็ทำงานได้เร็วขึ้นมาก!

3

PHP

ไม่มีอะไรดั้งเดิมเพียงแค่เฉลิมฉลองการโพสต์ครั้งแรกของฉันที่นี่

<?php

    $x = $argv[1];
    $y = $argv[2];
    $z = $argv[3];
    $count = 0;

    do
    {
        if (!(strpos($x, $z) === false))
            $count++;
        $x++;
    } while ($x <= $y);

    echo $count;

?>

อินพุต

php script.php 0 1000000 2

เอาท์พุต

468559


2

ทับทิม

นี่เป็นตัวอย่างที่ดีในการใช้ลด!

puts (ARGV[0]..ARGV[1]).reduce(0) { |c, n| n.to_s.include?(ARGV[2].to_s) ? c + 1 : c }

การป้อนข้อมูล:

ruby script.rb 0 1000000 2

เอาท์พุท:

468559

2

Python golf - 61

f=lambda x,y,z:len([i for i in range(x,y)if str(z)in str(i)])

งูหลามที่ไม่ใช่กอล์ฟ

def f(x, y, z):
    c = 0
    for i in range(x, y):
        c += str(z) in str(i)
    return c

2

Java8

การใช้ IntStream ใหม่สิ่งนี้จะกลายเป็นหนึ่งซับถ้าคุณไม่สนใจสิ่ง Java Framework บังคับ:

import java.util.stream.IntStream;
public class A{
  public static void main(String[] args){
    System.out.println(IntStream.rangeClosed(Integer.parseInt(args[0], Integer.parseInt(args[1])).filter(x -> ((Integer)x).toString().contains(args[2])).count());
  }
}

มันสามารถทำงานได้ที่นี่แม้ว่าฉันจะต้อง hardcode ค่า


โซลูชัน Java ที่น่าสนใจจริงๆ
Obl Tobl

2

F #

วิธีการแก้ปัญหานี้ใช้IndexOfในการค้นหาสตริงจากนั้นจำนวนเล็กน้อยเล่นซอเพื่อแปลงผลลัพธ์เป็น 1 หากพบและ 0 หากไม่พบจากนั้นผลรวม:

let count x y (z : string) = 
    [ x .. y ] |> Seq.sumBy(fun n -> min 1 (n.ToString().IndexOf z + 1))

และสามารถถูกเรียกเช่นนี้:

count 0 1000000 "2" // 468559

2

การแสดงออกปกติ

การติดตามจะนับ 1 หลักจนถึง 49

#!/bin/bash

echo "12313451231241241111111111111111111111111111111111111"  |\  
sed "s/[^1]//g;s/11111/5/g;s/1111/4/g;s/111/3/g;s/11/2/g;s/555555555/45/g;s/55555555/40/g;s/5555555/35/g;s/555555/30/g;s/55555/25/g;s/5555/20/g;s/555/15/g;s/55/10/g;s/54/9/g;s/53/8/g;s/52/7/g;s/51/6/g;s/50/5
/g;s/40/4/g;s/30/3/g;s/20/2/g;s/10/1/g"

2

R 23 25 27ตัวอักษร

เพิ่งได้รับเครื่องมือที่เหมาะสมสำหรับงาน ใช้ grep ใน R ง่าย ๆ ไม่มีอะไรแฟนซี

นี่คือสิ่งที่มันไม่: grepทุกกรณี2ในเวกเตอร์0จนและนับจำนวนผลการใช้10e6length

length(grep(2,0:100000,value=TRUE))

length(grep(2,0:10e6))

ผลลัพธ์: [1] 468559


Offcourse คุณสามารถเขียนฟังก์ชั่นที่ใช้ตัวเลขเป็นอินพุตเหมือนกับที่แสดงในตัวอย่าง

count = function(x=0, y=1000000, z=2){
  length(grep(z,x:y))
}

ตอนนี้คุณสามารถโทรหาcountด้วย x, y และ z หากไม่ได้ตั้งค่า (นั่นคือโดยค่าเริ่มต้น) ค่าสำหรับ x, y และ z คือ 0, 1000000 และ 2 ตามลำดับ ตัวอย่างบางส่วน:

count()
[1] 468559

หรือ

count(20, 222, 2)
[1] 59

หรือ

count(0, 100, 10)
[1] 2

บางคนคิดว่าเวลามีความสำคัญการใช้ฟังก์ชันนี้ใน R ใช้เวลาประมาณ 1 วินาที

system.time(count())
user  system elapsed 
0.979   0.003   0.981

อาจจะค่อนข้างสั้นเกินไป ;-)
Obll Tobl

ใช่นี่ไม่ใช่code-golfอยู่แล้ว :) ฉันสงสัยว่า: โปรแกรมจะเป็นอย่างไรถ้าต้องใช้ตัวเลขเป็นอินพุท (แทนที่จะเป็นฮาร์โค้ด)
Timwi

สร้างฟังก์ชันสำหรับ unimaginative;)
CousinCocaine

1

JavaScript (ES6), 63

f=(i,j,n)=>{for(c=0;i<=j;!~(''+i++).indexOf(n)?0:c++);return c}

การใช้งาน:

f(0, 1e6, 2)
> 468559

ยกเลิกแข็งแรงเล่นกอล์ฟ:

f = (i,j,n) => {
  for(
    // Initialize the counter.
    c=0;
    // Iterate through all integers.
    i<=j;
    // Convert current number into string then increment it.
    // Check if the digit appears into the current number.
    !~(''+i++).indexOf(n)
      // Occurence not found.
      ? 0
      // Occurence found.
      // Add 1 to the counter.
      : c++
  );
  return c
}

1

ทับทิม

โดยทั่วไปผมเอาคำตอบของปาโบลและกึ่งแข็งแรงเล่นกอล์ฟ (38 ตัวอักษรถ้าคุณวางช่องว่างที่ไม่จำเป็น) selectมันกลายเป็นตัวอย่างที่ไม่ให้ดีของการใช้

มันเลือกดัชนีในช่วงทุกที่มี(x .. y) zผลลัพธ์ระดับกลางนี้ถูกเก็บไว้ในอาเรย์ที่น่าเสียดายซึ่งขนาดจะถูกส่งกลับ

x,y,z = $*
p (x..y).select{ |i| i[z] }.size

มันดูเรียบร้อยทั้ง syntactically และ semantically ถึงแม้ว่าi[z]ส่วนนั้นดูเหมือนจะไม่เข้าท่าก็ตาม

มันใช้งานได้จริงxและyเป็นสตริงไม่ใช่ตัวเลข! ดังนั้นแต่ละiสตริงจึงเป็นเช่นกันและi[z]แน่นอนตรวจสอบว่ามีสตริงzอยู่iหรือไม่

$ ruby count-digits.rb 100 200 20
2
$ ruby count-digits.rb 0 1000000 2
468559

1

Python 2.7, 70 สัญญาณ

f = lambda x,y,z: sum(map(lambda x: str(z) in str(x), range(0, y+1)))

>>> f(0, 1000000, 2)
468559

ชอร์ต, 65 ป้าย

g = lambda x, y, z: sum(str(z) in str(i) for i in range(0, y+1))
>>> g(0, 1000000, 2)
468559

ฉันไม่คิดว่าคุณต้องการrange(0,y+1)ถ้าrange(y+1)ทำสิ่งเดียวกัน นอกจากนี้คุณสามารถลบมากที่สุดของช่องว่างเหล่านั้นถ้าคุณกำลังเล่นกอล์ฟ ...
SimonT


1

T-SQL

ถ้าฉันสามารถสมมติตัวแปร@X, @Yและ@Zที่มีอยู่:

ด้วยตารางตัวเลข (ขนาดใหญ่โดยพลการ; - 65)

select count(*)from n where n>=@X and n<=@Y and n like '%'+@Z+'%'

ด้วย CTE แบบเรียกซ้ำ - 127

with n(n)as(select @X union all select n+1 from n where n<@Y)select count(*)from n where n like'%'+@Z+'%'option(MAXRECURSION 0)

หากจำเป็นต้องกำหนดตัวแปรอย่างชัดเจน:

เพิ่ม 58 ทั้งสองคำตอบ - ตารางตัวเลข: 123, CTE แบบเรียกซ้ำ: 185

declare @X int=0;declare @Y int=100;declare @Z varchar(30)='2';

ฉันไม่ทราบเลยว่าหน่วยความจำที่ CTE แบบเรียกใช้ซ้ำสามารถใช้งานได้ แต่แน่นอนว่าจะไม่ชนะการแข่งขันความเร็วใด ๆ ตัวอย่างการค้นหา 2 ใน 0 ถึง 1000000 ใช้เวลา 8 วินาทีในระบบของฉัน

นี่คือSQL Fiddleถ้าใครอยากเล่นด้วย แบบสอบถาม 1000000 ใช้เวลา 30+ วินาทีในการเรียกใช้


ไม่เร็ว แต่สร้างสรรค์มาก!
Oblique Tobl

1

REBOL

; version 1 (simple loop counting)

count: func [x [integer!] y [integer!] z [integer!] /local total] [
    total: 0
    for n x y 1 [if found? find to-string n z [++ total]]
    total
]


; version 2 (build series/list and get length)

count: func [x [integer!] y [integer!] z [integer!]] [
    length? collect [for n x y 1 [if find to-string n z [keep true]]]
]

ตัวอย่างการใช้งานในคอนโซล Rebol (REPL):

>> count 0 1000000 2
== 468559

1

PowerShell

สองวิธีแก้ปัญหาทั้ง40 37 ตัวอักษร

สำหรับ PowerShell ทุกรุ่น:

$a,$b,$c=$args;($a..$b-match$c).count

PowerShell V3 และถึงมีนามแฝงสำหรับsls Select-Stringสิ่งนี้จำเป็นต้องมี@เพื่อบังคับอาร์เรย์หากมีเพียงหนึ่งค่าเท่านั้นที่จะทำการส่งผ่านไปป์ไลน์

$a,$b,$c=$args;@($a..$b|sls $c).count

1

ชุด

@setLocal enableDelayedExpansion&@set a=0&@for /L %%a in (%1,1,%2) do @set b=%%a&@if "!b:%3=!" NEQ "!b!" @set/aa+=1
@echo !a!

H:\uprof>count 0 1000000 2
468559

H:\uprof>count 1 2 3
0

อ่านง่ายขึ้นอีกเล็กน้อย -

@setLocal enableDelayedExpansion
@set a=0
@for /L %%a in (%1,1,%2) do (
    @set b=%%a
    @if "!b:%3=!" NEQ "!b!" @set/aa+=1
)
@echo !a!

ดีและเรียบง่าย ใช้การจัดการสตริงเพื่อตรวจสอบว่าตัวแปร!b!เหมือนกันกับตัวเองโดยไม่มีการป้อนข้อมูลจากผู้ใช้คนที่สาม%3( !b:%3=!)


1

มาติกา

วิธีแรก: สตริง

x, y, zจะถูกแปลงเป็นสตริง ถ้า string-integer ไม่ว่างzมันจะถูกนับ

f[{x_,y_},z_] :=Length[Select[ToString/@Range[Max[x, z], y], !StringFreeQ[#, ToString@z] &]]

ตัวอย่าง

f[{22, 1000}, 23]
f[{0, 10^6}, 2]

20
468559


วิธีที่สอง: รายการของตัวเลข

g[{x_,y_},z_]:=(t=Sequence@@ IntegerDigits@z;Length@Cases[IntegerDigits@Range[190], 
{s___,t,e___}])

ตัวอย่าง

g[{22, 1000}, 23]
g[{0, 10^6}, 2]

20
468559


Mathematica นั้นน่าหลงใหลอยู่เสมอแม้จะมีปัญหาง่าย ๆ
ก็ตาม

1

GolfScript

ฉันพยายามพัฒนาทักษะ GolfScript ของฉันดังนั้นฉันคิดว่าฉันจะตอบคำถามนี้ได้ นี่คือสิ่งที่ฉันมาด้วย:

`@@0\{.3$>}{.`4$?-1>@+\(}while@;;\;

สิ่งนี้สามารถพังทลายลงได้ดังนี้:

0 1000000 2    # parameters

`@@            # convert Z to string and put at bottom of stack
0\             # init counter and swap
{.3$>}         # loop condition: Y > X
{              # loop body
  .`           # convert to string
  4$?          # search for substring
  -1>@+        # if found add to counter
  \(           # decrement Y
}              # end loop body
while          # perform loop
@;;\;          # cleanup

แม้ว่าจะเป็น GolfScript โดยเป้าหมายก็ยิ่งพยายามทำให้มีประสิทธิภาพมากกว่าการกระชับดังนั้นฉันมั่นใจว่ามีบางคนสามารถชี้ให้เห็นถึงวิธีการต่าง ๆ ที่สามารถปรับปรุงได้

การสาธิต : โปรดทราบว่าฉันได้ลด Y ในการสาธิตเพื่อให้สามารถดำเนินการให้เสร็จภายใน <5 วินาที


1

PHP - 112

ไม่มีลูปที่สามารถมองเห็นได้ แต่มีหน่วยความจำหนักหน่วงเล็กน้อย!

<?=count(array_filter(range($argv[1],$argv[2]),function($i)use($argv){return strpos($i,$argv[3].'')!==false;}));

การใช้ php script.php 0 1000000 2


1

ECMAScript 3 ถึง 6

(javascript, JScript ฯลฯ )

ใช้ regex:

function f(x,y,z,r){for(r=0,z=RegExp(z);x<y;r+=+z.test(''+x++));return r}

ชำรุด:

function f(x,y,z,r){        // note argument `r`, eliminating the need for `var `
  for( r=0, z=RegExp(z)     // omitting `new` since ES will add it if omitted
     ; x<y                  // 
     ; r+=+z.test(''+x++)   // `x++` == post increment
                            // `''+Number` == convert Number to string
                            // `test` gives true | false
                            // `+Boolean` converts boolean to 1 | 0
                            // `r+=Number` incrementing r (were Number is always 1 or 0)
     );                     // no body thus semicolon is mandatory!
  return r;                 // returning r
}

ใช้ indexOf:

function f(x,y,z,r){for(r=0;x<y;r+=+!!~(''+x++).indexOf(z));return r}

ชำรุด:

function f(x,y,z,r){                // note argument `r`, eliminating the need for `var `
  for( r=0                          // omitting `new` since ES will add it if omitted
     ; x<y                          // 
     ; r+=+!!~(''+x++).indexOf(z)   // `x++` == post increment
                                    // `''+Number` == convert Number to string
                                    // `indexOf` returns index or `-1` when not found
                                    // `!!~ indexOf` converts sentinel value to boolean
                                    // `+Boolean` converts boolean to 1 | 0
                                    // `r+=Number` incrementing r (were Number is 1 or 0)
     );                             // no body thus semicolon is mandatory!
  return r;                         // returning r
}

ฟังก์ชั่นร่างกายเป็นถ่านหนึ่งตัวน้อยกว่าของ florent ดังนั้นเมื่อใช้=>สัญกรณ์ฟังก์ชั่นES6 ทั้งหมดจะเป็น 62 ถ่าน

ตัวอย่างการโทร: f(0,1e6,2)
ตัวอย่างการใช้:alert( f(0,1e6,2) );

JSFiddle ที่นี่

PS: ฟังก์ชั่นทั้งด้านบนกลับมาของพวกเขาในท้องถิ่นrตัวแปร
ดังนั้นเมื่อปล่อยตัวแปรผลลัพธ์rลงในขอบเขตส่วนกลางหนึ่งสามารถบันทึกอักขระได้อีก 10 ตัว:

function f(x,y,z){for(r=0;i<=j;r+=+!!~(''+i++).indexOf(z));}

ตัวอย่างการใช้: alert( f(0,1e6,2)||r );


1

Delphi - 120

บิตไปมากสำหรับรสนิยมของฉันจะดูว่าฉันสามารถออก

var x,y,z,i,c:int16;begin readLn(x,y,z);for i:=x to y do if inttostr(i).contains(inttostr(z))then inc(c);writeln(c);end.

ไม่ทราบระยะเวลาที่ฉันชอบที่จะเห็นการแก้ปัญหาที่เดลฟาย ;-)
OBL Tobl

@OblTobl ยอดเยี่ยม แต่มันสนุกมากที่จะลองทำให้มันสั้น: P
Teun Pronk

1

Python 2.7 - 50 ตัวอักษร

การประหยัดเล็กน้อยสำหรับคำตอบของ Python ที่มีอยู่

lambda x,y,z:sum(1for n in range(y-x)if`z+x`in`n`)

ใช้เทคนิคต่อไปนี้:

  • ผลรวมสามารถนำไปใช้กับเครื่องกำเนิดไฟฟ้าซึ่งแตกต่างจาก len ดังนั้นใช้ผลรวม (1 ... ) แทน len ([n ... ])
  • ใช้ `` แทน str () ซึ่งอนุญาตให้ ...
  • ฆ่าช่องว่างทั้งหมด - ดู '1for' และ 'if z+xin n'
  • ลบช่วงแรก () หาเรื่องโดยเริ่มต้นที่ 0 และทดสอบออฟเซต (จริง ๆ แล้ว ... ช่วยฉันไม่ได้เลย แต่ฉันชอบรูปลักษณ์ที่ดีกว่า :))

ในการดำเนินการ:

In [694]: (lambda x,y,z:sum(1for n in range(y-x)if`z+x`in`n`))(0,1000000,2)
Out[694]: 468559

1

k [28 ตัวอักษร]

{+/($x+!y)like"*",$:[z],"*"}

การใช้

{+/($x+!y)like"*",$:[z],"*"}[0;1000000;2]
468559

1
คุณสามารถบันทึกตัวอักษรโดยการแทนที่ด้วย$:[z] ($z)
mollmerx

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