整数の出現回数をカウントする[終了]


13

質問2を含む1,000,000未満の正の整数はいくつですか?。私はからInteger XY含むまでのすべてのInteger をカウントする最も創造的なソリューションを探していZます。 Z0〜の範囲で指定できますY

整数Zがより頻繁に表示される場合でも、見つかったすべての整数は1回だけカウントされます。例えば:

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

この問題を解決するのは難しくないので、それは単なるです。2月28日までに投稿された最も投票された回答が勝ちです!


あなたの投稿からは完全に明確ではありませんが、Zは0からinfの間にあると思いますか?または、0から9の間ですか?
mmumboss 14


@OblTobl本当にZ> Yのケースを明示的に除外しますか?その場合、期待される出力が0にならないのはなぜですか?
ランチャー

@Cruncher気にしない!しかし、それは少し役に立たないと思います
;

これは、それNが可能で123あり、サブストリング123が存在する場合にのみ一致することを意味しますか?
ポプラ14

回答:


26

バッシュ(20)

seq $1 $2|grep -c $3

使用法

$ bash count.sh 0 1000000 2
468559

10
呼び出しがプログラム自体より長い場合、それは面白いです
;

11

機能

いつものように、StackExchangeによって追加された行の高さが行を分割するため、実行を検討してください $('pre').css('line-height',1)、ブラウザーコンソールでしてそれを修正することをてください。

私の他のFuncitonの回答とは異なり、これは関数宣言を使用しません。それは単なるプログラムです。ただし、ラムダ式を使用します。12月にFuncitonに追加した機能です。

入力は、スペース(すなわちx y z)で区切られた3つの10進整数(負の場合もある)として期待されます。実際、z任意の文字列を使用できます。たとえば、間隔内の負の数の数を数えるのは、マイナス記号(、U + 2212)だけです:)

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

1
それはいいね!言語を使用してあなた自身作られた
pcnThird

2
@pcnThird:ティムウィは、ゴルフをするか、ゴルフをするための言語を作成するのに時間を費やしていると思います(スクリプティングも参照)。
ゲイブ14

10

C#

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

賢い解決策!あなたがループなしでそれをしたことが好きです。
Obl Tobl

目に見えるループのない@OblTobl 。
ジャスティン14

もちろん、とにかくいい
Obl Tobl 14

1
バグがあり、.Range受け入れますが(int start, int count)、受け入れません(start, end)。私は常に自分自身でこのtrapに陥ります:)
Grozz 14

これをメモ帳ですばやくノックアップするのに役立ちます...コードが修正されたので、今は正しいです!
Mo D 14

5

APL(29)

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

これはZ、左引数[X,Y]として間隔を、右引数として間隔をとる関数です。

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

本当に明確ではない...しかし本当にクール!
Obl Tobl 14

4

Python 2.7

ニード・フォー・スピード

説明

enter image description here

実装

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

比較

@デニス

$ \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任意であることができる整数、はなく、数字の間lohi
デニス14

それも長くなりますけれども、数学的解決策は...、まだそこにある
レッドアラート

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

素敵で明確なもの!
Obl Tobl

使用して4文字長さを短縮echoできるのにseq、なぜ使用するのですか?(1交換する中括弧及び1を省略することができるためのコマンド、2の長さのために..単一のスペースを伴う)
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

3

Scala:

args(0).toInt to args(1).toInt count (_.toString contains args(2))


2

ルビー

これはreduceを使用する素晴らしい例です!

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

パイソンゴルフ-61

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

Python非ゴルフ

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フレームワークを無視した場合、これは本質的に1つのライナーになります。

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

ここで実行できますが、値をハードコーディングする必要がありました。


本当に面白い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

正規表現

以下は49まで1の桁を数えます。

#!/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チャー

仕事にぴったりのツールを入手してください。Rでgrepを簡単に使用できます。

これは、それが行うことです:までのベクター内のgrepすべてのインスタンスで2、を使用して結果の数をカウントします。010e6length

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

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

結果: [1] 468559


オフコースでは、例に示されているように、入力として数値を受け取る関数を作成できます。

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

多分それは非常に短いです;-)
Obl Tobl 14

まあ、これはとにかくコードゴルフではありません:)私は疑問に思います:入力として数字を(それらをハードコーディングするのではなく)受け取らなければならなかった場合、プログラムはどのように見えるでしょうか?
ティムウィ14

想像力に欠ける機能を作成しました;)
CousinCocaine 14

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

ルビー

基本的には、Pabloの答えをセミゴルフ(不要な空白を削除する場合は38文字)を使用して、それほど素晴らしいものではない例を使用しましたselect

範囲内のすべてのインデックスを選択します (x .. y)を含むしますz。残念ながら、この中間結果は配列に格納され、そのサイズが返されます。

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

i[z]部分的には意味をなさないように見えますが、構文的にも意味的にもかなりきれいに見えます。

xy実際に文字列であり、数字ではないために動作します!したがって、それぞれ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

Rubyの使用Enumerable#grep

start, stop, target = $*
p (start..stop).grep(Regexp.new target).size

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がどれだけのメモリを使用できるかはわかりませんが、スピードコンテストには勝てません。0から1000000で2を検索する例では、システムで8秒かかります。

誰かがそれで遊んでみたいなら、これはSQL Fiddleです。1000000クエリの実行には30秒以上かかります。


速くはありませんが、非常に創造的です!
Obl Tobl 14

1

レボル

; 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

パワーシェル

2つのソリューション、両方とも40 37文字の。

PowerShellのすべてのバージョン:

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

PowerShell V3以降にはのslsエイリアスがありSelect-Stringます。これ@により、パイプラインを介して1つの値のみが配列を作成する場合、配列を強制する必要があります。

$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番目のユーザー入力%3!b:%3=!)なしで変数がそれ自体と同じかどうかを確認します。


1

Mathematica

最初の方法:文字列

x, y, z文字列に変換されます。文字列整数にが含まれていない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


2番目の方法:数字のリスト

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はさえ、単純な問題のために、常に魅力的である
OBL Tobl

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など)

正規表現を使用:

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より1文字少ないため、ES6 =>関数表記を使用する場合、合計は62文字になります

呼び出し例:f(0,1e6,2)
使用例:alert( f(0,1e6,2) );

ここにJSF

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

デルファイ-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 14

@OblTobl素晴らしいですが、短くするのはとても楽しいです:P
テウンプロンク14

1

Python 2.7-50文字

既存のPython回答の節約。

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

次のトリックを使用します。

  • lenとは異なり、sumはジェネレータに適用できるため、len([n ...])の代わりにsum(1 ...)を使用してください。
  • str()の代わりに ``を使用します。これにより、...
  • すべてのスペースを削除-「1for」および「if z+xin 」を参照n」を参照
  • 0から開始してオフセットをテストすることにより、最初のrange()argを削除します(実際には...何も保存しませんが、見た目は良くなります:))

動作中:

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 14

ただし、ソリューションの上限は正しくありません。xからyではなく、xからx + y-1まで列挙します。
mollmerx
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.