Щільність цифр з цифрами


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 в межах від 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. Пітон: 245

Тепер, коли було обрано відповідь, ось моя (нерозроблена) посилання на реалізацію в JavaScript: http://jsfiddle.net/ywc25/2/

Відповіді:


3

Рубін 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): Фіксований вихід у разі прив'язки.

@ Вентеро: не вдається обидва тестові випадки. Я думаю, ви забуваєте залишити квадрати, починаючи з 0 *
mellamokb

@mellamokb: Чи не підведемо їх тут: $ ruby1.9 sndd.rb 14000 15000 => 14441. x[0]>?0чеки на квадрати, що починаються з 0.
Вентеро

@mellamokb: Тут проходять тестові приклади.
Nabb

@ Вентеро: Хм .. щось не повинно бути з моїм середовищем тестування на рубіні. Я не знайомий з Рубі. У мене є 1,87, я думаю, і я скопіював / вставив код вище в sndd.rb, потім запустити з ruby sndd.rb 14000 15000Windows, я отримаю 14000.
mellamokb

@mellamokb: У Ruby 1.8 ?0- це Fixnum, тоді як у Ruby 1.8 - це рядок, тому порівняння, яке я згадав, має інше значення залежно від версії Ruby (насправді воно повинно кинути виняток у 1.8). Тому я в назві явно згадував версію 1.9.
Вентеро

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

@ESutanik: Я не думаю, що послідовність пов'язана, оскільки вони вимагають, щоб ціле число було квадратним - у моїй послідовності єдині квадратики є невеликими підрядками (<= 5 цифр), якщо випадково немає більшого.
Кіт Рендалл

Ви також можете створити нескінченну послідовність, коли посилання породжує зайвий квадрат, тобто щось, що закінчується на 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]

Завдяки Вентеро за однобайтне скорочення я був занадто дурним, щоб знайти себе.

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

Пітон, 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 ∈ ℕ ∀ i ∈ ℕ n : SNDD ( n ) ≥ SNDD ( i ).

Доказ ескіз . Набір квадратів з цифрами 1, 4 і 9, ймовірно, кінцевий . ∎


Спробуйтеrange(*map(int,sys.argv[1:]))
Кіт Рендалл

1
Концепція 2 помилкова, якщо послідовність 1,75-збіжної послідовності в моїй відповіді дає найкращі оцінки (великі, якщо, правда,), оскільки наступні елементи послідовності назавжди кращі, назавжди.
Кіт Рендалл

Концепція 2 помилкова у відповіді @ Арнта, оскільки значення 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).
Арнт Веенстра

Код для пошуку квадратів: jsfiddle.net/zVSuZ/2
mellamokb

@Arnt: Ось така (тривіальна) послідовність, 5 ^ 2 (1/2), 55 ^ 2 (2/4), 5055 ^ 2 (3/8), 50005055 ^ 2 (4/16) тощо. де кожне додавання дорівнює 5 * 10 ^ n, де n вдвічі перевищує попередній запис. Кожен запис стає меншим за показник, але ліміт при застосуванні правила додавання двох 00 зростає незначно більше, тому обмеження (1/2), (2/2), (3/2), (4/2) тощо .
mellamokb

Так, це ідея, яка підтверджує будь-яке значення для SNDD.
Арнт Веенстра

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)

Програма, мабуть, цікавіша без того - таким чином вона повертає всі числа максимальної щільності, а не лише одне - але я додав її, щоб відповідати специфікації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.