ความหนาแน่นตัวเลขจำนวนสแควร์


17

ความหนาแน่นเลขฐานสองจำนวน (SNDD) ของตัวเลข - คิดค้นด้วยตัวเอง - คืออัตราส่วนของการนับจำนวนสแควร์ที่พบในหลักต่อเนื่องกับความยาวของตัวเลข ตัวอย่างเช่น 169 เป็นตัวเลข 3 หลักที่มี 4 ช่องสี่เหลี่ยมคือ 1, 9, 16, 169 - และดังนั้นจึงมีความหนาแน่นตัวเลขสี่หลักเท่ากับ 4/3 หรือ 1.33 หมายเลข 4 หลัก 1444 มี 6 สี่เหลี่ยมจัตุรัส - 1, 4, 4, 4, 144, 1444 - และทำให้อัตราส่วน 6/4 หรือ 1.5 โปรดสังเกตในตัวอย่างก่อนหน้านี้ที่อนุญาตให้ทำซ้ำได้ นอกจากนี้ไม่อนุญาต 441 เพราะไม่สามารถพบได้อย่างต่อเนื่องภายในหมายเลข 1444

งานของคุณคือการเขียนโปรแกรมที่ค้นหาช่วงที่กำหนด A - B (รวมอยู่ด้วย) เพื่อหาจำนวนที่มีความหนาแน่นตัวเลขสูงสุดที่เป็นรูปสี่เหลี่ยมจัตุรัส โปรแกรมของคุณควรปฏิบัติตามข้อกำหนดต่อไปนี้:

  • ใช้อินพุต A, B ในช่วง 1 ถึง 1,000,000,000 (1 พันล้าน) ตัวอย่าง:sndd 50 1000
  • ส่งคืนผลลัพธ์เป็นตัวเลขที่มี SNDD ที่ใหญ่ที่สุด ในกรณีที่เสมอกันให้ส่งคืนจำนวนที่น้อยที่สุด
  • 0 จะไม่นับเป็นรูปสี่เหลี่ยมในรูปแบบใด ๆ 0, 00, 000 และอื่น ๆ ทั้งสองจะเริ่มต้นด้วย 0 เช่น 049 หรือ 0049
  • โปรดทราบว่าจำนวนทั้งหมดไม่จำเป็นต้องเป็นตัวเลขจตุรัส

ตัวอย่าง:

sndd 14000 15000
Output: 14441

sndd 300 500
Output: 441

โบนัส: SNDD ที่มีจำนวนมากที่สุดระหว่าง 1 ถึง 1,000,000,000 คืออะไร คุณสามารถพิสูจน์ได้ว่านี่เป็นสิ่งที่ใหญ่ที่สุดหรืออาจมีขนาดใหญ่กว่าในช่วงที่สูงขึ้นได้ไหม

คะแนนปัจจุบัน:

  1. ทับทิม: 142
  2. Windows PowerShell: 153
  3. สกาล่า: 222
  4. Python: 245

ตอนนี้เลือกคำตอบแล้วนี่คือการนำการอ้างอิง (ungolfed) ของฉันไปใช้ใน JavaScript: http://jsfiddle.net/ywc25/2/

คำตอบ:


3

Ruby 1.9, 142 ตัวอักษร

$><<($*[0]..$*[1]).map{|a|n=0.0;(1..s=a.size).map{|i|n+=a.chars.each_cons(i).count{|x|x[0]>?0&&(r=x.join.to_i**0.5)==r.to_i}};[-n/s,a]}.min[1]
  • (139 -> 143): แก้ไขเอาต์พุตในกรณีที่เสมอกัน

@Ventero: ล้มเหลวทั้งสองกรณีทดสอบ ฉันคิดว่าคุณลืมที่จะออกจากสี่เหลี่ยมเริ่มต้นด้วย 0 *
mellamokb

@mellamokb: $ ruby1.9 sndd.rb 14000 15000 => 14441ไม่ล้มเหลวพวกเขาที่นี่: x[0]>?0ตรวจสอบสี่เหลี่ยมเริ่มต้นด้วย 0
Ventero

@mellamokb: มันผ่านกรณีทดสอบที่นี่
Nabb

@Ventero: อืม .. มีบางอย่างผิดปกติกับสภาพแวดล้อมการทดสอบทับทิมของฉัน ฉันไม่คุ้นเคยกับรูบี้ ฉันมี 1.87 ฉันคิดว่าและฉันคัดลอก / วางรหัสข้างต้นลงใน sndd.rb แล้วทำงานด้วยruby sndd.rb 14000 15000จาก Windows ฉันจะได้รับ 14,000
mellamokb

@mellamokb: ใน Ruby 1.8 ?0เป็น Fixnum ในขณะที่ Ruby 1.8 เป็นสตริงดังนั้นการเปรียบเทียบที่ฉันกล่าวถึงมีความหมายต่างกันขึ้นอยู่กับรุ่น Ruby (จริง ๆ แล้วมันควรจะมีข้อยกเว้นใน 1.8) นั่นเป็นเหตุผลที่ฉันพูดถึงรุ่น 1.9 ในชื่อเรื่องอย่างชัดเจน
Ventero

8

ตอบโบนัส: คะแนนที่ดีที่สุดสำหรับตัวเลข <1e9 คือ 5/3 = 1.666 ... สร้างโดย 144411449 (และอาจเป็นอย่างอื่น?)

แต่คุณสามารถทำได้ดีกว่าด้วยจำนวนที่มากขึ้น โดยทั่วไปถ้า n มีคะแนนเป็น x คุณสามารถต่อกันสองสำเนาของ n และได้คะแนนเดียวกัน x หากคุณโชคดีและ n มีหลักแรกและหลักสุดท้ายเหมือนกันคุณสามารถดรอปหนึ่งในหลักเหล่านั้นในการต่อกันและปรับปรุงคะแนนของคุณเล็กน้อย (หนึ่งน้อยกว่าสองเท่าของจำนวนสแควร์สและหนึ่งน้อยกว่าสองเท่าของจำนวนหลัก) .

n = 11449441 มีคะแนน 1.625 และมีหลักแรกและตัวสุดท้ายเหมือนกัน ด้วยความจริงนั้นเราได้คะแนนตามลำดับดังนี้:

1.625 for 11449441
1.666 for 114494411449441
1.682 for 1144944114494411449441
1.690 for 11449441144944114494411449441
1.694 for 114494411449441144944114494411449441

ซึ่งให้ลำดับที่ไม่มีที่สิ้นสุดของตัวเลขซึ่งเคร่งครัด (แม้ว่าจะลดลง) ดีกว่าตัวเลขก่อนหน้าและทั้งหมดยกเว้น 2 อันดับแรกดีกว่าคะแนนที่ดีที่สุดสำหรับตัวเลข <1e9

ลำดับนี้อาจไม่ใช่ภาพรวมที่ดีที่สุด มันแปรสภาพเป็นคะแนน จำกัด (12/7 = 1.714) และอาจมีตัวเลขอื่นที่มีคะแนนดีกว่าขีด จำกัด

แก้ไข : ลำดับที่ดีกว่ามาเป็น 1.75

1.600 14441
1.667 144414441
1.692 1444144414441
1.706 14441444144414441
1.714 144414441444144414441

! ที่น่าสนใจ คุณอาจพิสูจน์ได้ว่าลำดับนี้ไม่มีที่สิ้นสุดจริง
ESultanik

@ESultanik: ไม่จริงเพราะไม่มีความต้องการที่นี่ที่จำนวนโดยรวมเป็นตารางที่สมบูรณ์แบบ
mellamokb

@ สุตานิก: ฉันไม่คิดว่าลำดับนั้นเกี่ยวข้องกันเนื่องจากพวกเขาต้องการจำนวนเต็มเป็นสแควร์ - ในลำดับของฉันสแควร์เดียวเท่านั้นคือการเรียงลำดับขนาดเล็ก (<= 5 หลัก) เว้นแต่ว่าจะมีขนาดใหญ่กว่าโดยบังเอิญ
Keith Randall

นอกจากนี้คุณยังสามารถสร้างลำดับที่ไม่มีที่สิ้นสุดที่ลิงก์สร้างสแควร์พิเศษเช่นบางสิ่งที่ลงท้ายด้วย 44 และเริ่มต้นด้วย 1 จะทำให้ 441 กับทุกชุดค่าผสม ตัวอย่างเล็ก ๆ น้อย ๆ จะเป็นลำดับ 144, 144144, 144144144 เป็นต้น
mellamokb

@ mellamokb ว้าวฉันพลาดไปโดยสิ้นเชิงว่าตัวเลขไม่จำเป็นต้องเป็นสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบ คุณถูก.
ESultanik

3

Windows PowerShell, 153 154 155 164 174

$a,$b=$args
@($a..$b|sort{-(0..($l=($s="$_").length)|%{($c=$_)..$l|%{-join$s[$c..$_]}}|?{$_[0]-48-and($x=[math]::sqrt($_))-eq[int]$x}).Count/$l},{$_})[0]

ขอบคุณ Ventero สำหรับการลดขนาดหนึ่งไบต์ฉันโง่เกินไปที่จะพบตัวเอง

เวอร์ชัน 154- ไบต์อธิบาย:

$a,$b=$args   # get the two numbers. We expect only two arguments, so that
              # assignment will neither assign $null nor an array to $b.

@(   # @() here since we might iterate over a single number as well
    $a..$b |  # iterate over the range
        sort {   # sort
            (   # figure out all substrings of the number
                0..($l=($s="$_").length) | %{  # iterate to the length of the
                                               # string – this will run off
                                               # end, but that doesn't matter

                    ($c=$_)..$l | %{       # iterate from the current position
                                           # to the end

                        -join$s[$c..$_]    # grab a range of characters and
                                           # make them into a string again
                    }
                } | ?{                     # filter the list
                    $_[0]-48 -and          # must not begin with 0
                    ($x=[math]::sqrt($_))-eq[int]$x  # and the square root
                                                     # must be an integer
                }

            ).Count `  # we're only interested in the count of square numbers
            / $l       # divided by the length of the number
        },
        {-$_}  # tie-breaker
)[-1]  # select the last element which is the smallest number with the
       # largest SNDD

2

Python, 245 256

import sys
def t(n,l):return sum(map(lambda x:int(x**0.5+0.5)**2==x,[int(n[i:j+1])for i in range(l)for j in range(i,l)if n[i]!='0']))/float(l)
print max(map(lambda x:(x,t(str(x),len(str(x)))),range(*map(int,sys.argv[1:]))),key=lambda y:y[1])[0]
  • 256 → 245: การทำความสะอาดขึ้นขอบคุณรหัสอาร์กิวเมนต์แยกปลายจากคีแรนดัล

สิ่งนี้อาจสั้นกว่านี้มากหากช่วงถูกอ่านจากstdinตรงข้ามกับอาร์กิวเมนต์บรรทัดคำสั่ง

แก้ไข:

เกี่ยวกับโบนัสการทดลองของฉันแนะนำดังต่อไปนี้:

การคาดคะเน 1 . ทุก n ∈ℕ จำนวนในnมีขนาดใหญ่ที่สุด SNDD ต้องมีเพียงตัวเลข 1, 4 และ 9

การคาดคะเน 2.n ∈ℕ∀ฉันℕ∈ n : SNDD ( n ) ≥ SNDD ( ฉัน )

ร่างหลักฐาน ชุดของสี่เหลี่ยมที่มีตัวเลข 1, 4 และ 9 มีแนวโน้มที่ จำกัด ∎


ลองrange(*map(int,sys.argv[1:]))
Keith Randall

1
การคาดเดา 2 เป็นเท็จถ้าลำดับ 1.75- บรรจบกันในคำตอบของฉันผลิตคะแนนที่ดีที่สุด (ใหญ่ถ้ายอมรับได้) เนื่องจากองค์ประกอบที่ตามมาของลำดับนั้นดีขึ้นเล็กน้อยตลอดไป
Keith Randall

การคาดเดา 2 เป็นเท็จโดยคำตอบของ @ Arnt เนื่องจากค่าของ SNDD สามารถทำให้มีขนาดใหญ่โดยพลการ
mellamokb

2

สกาลา, 222

object O extends App{def q(i: Int)={val x=math.sqrt(i).toInt;x*x==i}
println((args(0).toInt to args(1).toInt).maxBy(n=>{val s=n+""
s.tails.flatMap(_.inits).filter(x=>x.size>0&&x(0)!='0'&&q(x.toInt)).size.toFloat/s.size}))}

(ต้องใช้ Scala 2.9)


1

พิจารณาคำถามโบนัส: นอกขอบเขต SNDD ที่เป็นไปได้สูงสุดนั้นไม่มีที่สิ้นสุด

อย่างน้อยถ้าฉันอ่านคำถามถูกต้องจะมีการนับจำนวนสี่เหลี่ยมเช่น 100 (10 * 10)

หากคุณพิจารณาหมายเลข 275625 คะแนนจะเป็น 5/6 เนื่องจาก 25, 625, 5625, 75625 และ 275625 เป็นสี่เหลี่ยมจัตุรัสทั้งหมด

การเพิ่ม 2 ศูนย์ให้: 27562500 ซึ่งมีคะแนน 10/8 ขีด จำกัด ของลำดับนี้คือ 5/2 = 2.5

ในบรรทัดเดียวกันคุณสามารถค้นหาสี่เหลี่ยมที่ลงท้ายด้วยจำนวนสี่เหลี่ยมเล็ก ๆ ที่ต้องการ ฉันพิสูจน์ได้ แต่คุณคงเข้าใจแล้ว

เป็นที่ยอมรับว่านี่ไม่ใช่วิธีแก้ปัญหาที่ดีมาก แต่มันพิสูจน์ได้ว่าไม่มีขีด จำกัด บน SNDD


"'ในบรรทัดเดียวกันคุณสามารถค้นหาสี่เหลี่ยมที่ลงท้ายด้วยจำนวนสี่เหลี่ยมจัตุรัสเล็ก ๆ ที่ต้องการฉันสามารถพิสูจน์เรื่องนี้ได้ แต่คุณอาจได้แนวคิดนี้" ฉันต้องการที่จะเห็นหลักฐานนี้ได้รับการพัฒนา ฉันสามารถเห็นลำดับที่ใหญ่ที่สุดที่สิ้นสุดใน 25 ที่ทุกหมายเลขที่ลงท้ายด้วย 25 คือ 275625 สแควร์ไม่มีหลัก 1-9 คุณสามารถวางบนจุดเริ่มต้นเพื่อค้นหาสแควร์อื่น คุณกำลังพูดว่าสิ่งนี้สามารถทำให้มีขนาดใหญ่โดยพลการและถ้าเป็นเช่นนั้นอย่างไรและทำไม?
mellamokb

ใช่ลำดับสามารถทำให้ใหญ่โดยพลการ หลักฐานคือ: ถ้า a * a = b เป็นหมายเลขเริ่มต้นของคุณดังนั้น (a + 10 ^ c) * (a + 10 ^ c) จะสิ้นสุดด้วย b หาก c มีขนาดใหญ่พอสมควร ในทางปฏิบัติอาจมีตัวเลขที่เล็กกว่าซึ่งลงท้ายด้วย b ถ้าคุณหาสี่เหลี่ยม ตัวอย่างเช่น 18275625 เป็นสี่เหลี่ยมจัตุรัส (4275 * 4275)
Arnt Veenstra

รหัสเพื่อค้นหาช่องสี่เหลี่ยม: jsfiddle.net/zVSuZ/2
mellamokb

@ Arnt: นี่คือลำดับ (เล็กน้อย) เช่น 5 ^ 2 (1/2), 55 ^ 2 (2/4), 5055 ^ 2 (3/8), 5,0005055 ^ 2 (4/16) เป็นต้น โดยที่การเพิ่มแต่ละรายการคือ 5 * 10 ^ n โดยที่ n เป็นสองเท่าของรายการก่อนหน้า แต่ละรายการมีคะแนนน้อยกว่า แต่ขีด จำกัด เมื่อใช้กฎเพิ่มสอง 00 จะขยายใหญ่ขึ้นเล็กน้อยดังนั้นข้อ จำกัด คือ (1/2), (2/2), (3/2), (4/2) ฯลฯ .
mellamokb

ใช่นั่นเป็นแนวคิดที่จะพิสูจน์คุณค่าใด ๆ ของ SNDD
Arnt Veenstra

1

Clojure - 185 ตัวอักษร

อาจได้รับการปรับให้เหมาะสมยิ่งขึ้นไปอีก แต่นี่จะเป็น:

(fn[A,B]((first(sort(for[r[range]n(r A(inc B))s[(str n)]l[(count s)]][(/(count(filter #(=(int%)(max 1%))(for[b(r(inc l))a(r b)](Math/sqrt(Integer/parseInt(subs s a b))))))(- l))n])))1))

ใช้เป็นฟังก์ชั่นที่มีสองพารามิเตอร์:

(crazy-function-as-above 14000 15000)
=> 14441

1

เยลลี่ขนาด 21 ไบต์ภาษาโพสต์วันที่ท้าทาย

DµẆ1ị$ÐfḌƲS÷L
rµÇÐṀḢ

ลองออนไลน์!

คำอธิบาย

ฟังก์ชั่นตัวช่วย (คำนวณความหนาแน่นหลักของอินพุต):

DµẆ1ị$ÐfḌƲS÷L
Dµ              Default argument: the input's decimal representation
  Ẇ             All substrings of {the decimal representation}
      Ðf        Keep only those where
   1ị$          the first digit is truthy (i.e. not 0)
        Ḍ       Convert from decimal back to an integer
         Ʋ     Check each of those integers to see if it's square
           S    Sum (i.e. add 1 for each square, 0 for each nonsquare)
            ÷L  Divide by the length of {the decimal representation}

โปรแกรมหลัก:

rµÇÐṀḢ
rµ              Range from the first input to the second input
  ÇÐṀ           Find values that maximize the helper function
     Ḣ          Choose the first (i.e. smallest)

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

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