Вернуть целые числа с квадратными цифрами


31

Введение и кредит

Мы все знаем и любим наши замечательные правила, чтобы проверить, делится ли число на 11 или 3, что является просто некоторой умной суммой по цифрам числа. Теперь этот вызов выводит это на новый уровень, требуя, чтобы вы вычислили сумму цифр, а затем проверили, является ли результат идеальным целочисленным квадратом, и ни одна из этих операций обычно не может быть выполнена очень короткой. Так как это свойство также очень трудно увидеть при просмотре числа, мы хотим, чтобы это было сделано для целых списков чисел, чтобы мы могли сохранить человеческую работу. Так что это ваша задача сейчас!

Это было задание на моем курсе функционального программирования в университете. Это задание теперь закрыто и обсуждалось в классе, и у меня есть разрешение моего профессора опубликовать его здесь (я спросил явно).

Спецификация

вход

Ваш ввод - это список неотрицательных целых чисел в любом стандартном формате ввода / вывода.
Вы можете выбрать формат списка, так как это нужно вашему языку

Выход

Вывод представляет собой список целых чисел в любом стандартном формате ввода / вывода.

Что делать?

Отфильтруйте каждое целое число из списка ввода, для которого сумма цифр не является квадратом (целого числа).
Порядок элементов не может быть изменен, например, если вы получите, [1,5,9]вы не можете вернуться[9,1]

Потенциальные угловые случаи

0 является неотрицательным целым числом и, следовательно, допустимым входным значением, а 0 также является действительным целочисленным корнем, например, 0 считается целочисленным квадратом.
Пустой список также является допустимым входом и выходом.

Кто выигрывает?

Это код-гольф, поэтому выигрывает самый короткий ответ в байтах!
Стандартные правила применяются конечно.

Тестовые случаи

[1,4,9,16,25,1111] -> [1,4,9,1111]
[1431,2,0,22,999999999] -> [1431,0,22,999999999]
[22228,4,113125,22345] -> [22228,4,22345]
[] -> []
[421337,99,123456789,1133557799] -> []

Пошаговый пример

Example input: [1337,4444]
Handling first number:
Sum of the digits of 1337: 1+3+3+7=14
14 is not an integer square, thus will be dropped!
Handling second number:
Sum of the digits of 4444: 4+4+4+4=16
16 is an integer square because 4*4=16, can get into the output list!
Example output: [4444]

11
Хороший первый вызов, и добро пожаловать на сайт!
DJMcMayhem

Для будущих задач обратите внимание на песочницу . Это место, где мы ставим задачи, прежде чем размещать их на главном сайте, чтобы они могли получить обзор и запросить их содержание, чтобы они (надеюсь) получили лучший прием на главной странице. Не то, чтобы это был плохой вопрос (мне на самом деле очень нравится)
Blue

@muddyfish, я читал об этом и рассматривал возможность размещения там, но решил не делать этого, потому что я был уверен, что я ничего не могу упустить / сделать ужасно неправильно здесь :) Конечно, если у меня есть хоть какие-то сомнения, что-то может быть Я скучаю, я отправлю туда.
SEJPM

12
Несмотря на то, что совершенно нормально избегать «песочницы», если бы вы разместили там сообщение, я бы посоветовал вам принять участие только в тестировании отдельного целого числа. Интересное задание - это тест, обертывание которого заданием фильтра не особенно интересно. Все, что он делает, - это существенно усложняет задачу в эзотерических языках, в которых нет массивов в качестве типов. Это может показаться немного резким, но это все еще отличный первый пост. Просто сказать, что песочница есть, потому что, как бы ты ни был уверен, ты ничего не пропустил, ты что-то упустил.
FryAmTheEggman

1
@FryAmTheEggman Я могу сказать для Mathematica, что создание этой функции для отображения в списках усложняет ситуацию немного нетривиальным образом, так что это не совсем скучно.
LLlAMnYP

Ответы:



5

Mathematica, 39 36 байт

Анонимная функция:

Select[AtomQ@√Tr@IntegerDigits@#&]

LLlAMnYP сохранил байт. Спасибо!

Мартин Эндер спас еще три, заменив IntegerQна AtomQ. Умная! (Результат будет точным, поэтому он возвращает составное выражение, как Sqrt[5]если бы его аргумент не был квадратом.)


Байт для сохранения ...Digits@#&вместо...Digits[#]&
LLlAMnYP


4

Brachylog v2, 8 байт

{ẹ+√ℤ&}ˢ

Попробуйте онлайн!

объяснение

{ẹ+√ℤ&}ˢ
{     }ˢ  Map the following operation over {the input}, discarding elements that error:
 ẹ         Split into a list of digits
  +        Sum that list
   √       Take its square root
    ℤ      Assert that the result is an integer
     &     Return to the original value

В &означает , что выходные элементы являются таким же , как в списке ввода, но выдаст ошибку , если вход блока не является квадратным числом, таким образом мы получаем список ввода с элементами с неквадратными значными суммами отбрасываются.

Обратите внимание, что на первый взгляд может показаться, что здесь существует проблема погрешности с плавающей запятой (некоторые очень большие неквадратные целые числа имеют целочисленные квадратные корни из-за округления). Однако Brachylog поддерживает арифметику bignum и фактически учитывает это поведение в своей реализации : число, представляющее собой идеальный квадрат, получит квадратный корень в виде целого числа, тогда как число, которое не является идеальным квадратом (но достаточно близко, чтобы его корень квадратный является интегральным), квадратный корень будет представлен как число с плавающей точкой с целым значением. Удобно, только разрешает первый тип возвращаемого значения, давая сбой утверждения для второго.



3

CJam, 14 байтов

Спасибо @FryAmTheEggman за сохранение одного байта!

{{Ab:+mq_i=},}

Попробуйте онлайн!

Это неназванный блок, который ожидает входной список в стеке и оставляет в нем отфильтрованный список.

объяснение

{e # начать новый блок
 Ab e # преобразовать в базу 10 -> разделить число на цифры
 : + e # сумма th цифр
 mq e # получить квадратный корень
 _ e # дублировать результат
 то есть # конвертировать в целое число
 = e # проверить, равны ли преобразованный квадратный корень и исходный
} e # end block
, e # отфильтровать список ввода

3

Haskell - 70 60 59 байт

f=filter(\x->elem(sum.map(read.pure).show$x)$map(^2)[0..x])

Использование:

> f [0..100]
[0,1,4,9,10,13,18,22,27,31,36,40,45,54,63,72,79,81,88,90,97,100]

Довольно просто; вычисляет сумму цифр и проверяет, является ли floor (sqrt (y)) ^ 2 == y

Редактировать: украл идею проверки списка квадратов от C. Quilley


2
Интересный подход. Я не уверен, что f=требуется для этого ответа.
Майкл Кляйн

3

05AB1E, 19 10 байт

vySOtDï->—

объяснение

vy                     # for each int in list
  SO                   # digit sum
    tDï-               # difference between sqrt() and int(sqrt())
        >              # increase by 1 giving 1 (true) when equal
         —             # print current int in list if truthy

Попробуйте онлайн

Редактировать: 9 байтов сохранено благодаря @Adnan


Чтобы получить сумму цифр для каждого, вы можете vySOсразу же проверить и проверить, квадрат это или нет. Я получил это до 5: tDï->. Также есть специальная встроенная функция, которая печатает yпри равенстве 1, то есть ( ). Так что это будет vySOtDï->—.
Аднан

@ Adnan: я не могу поверить, что я забыл о S. Я даже не смотрел на него - поскольку задача сказала выводить в виде списка, но я вижу, что другие ответы делают то же самое, поэтому я предполагаю, что все в порядке.
Эминья

Да, элементы, разделенные символом новой строки, принимаются по умолчанию, я думаю, если только в вызове явно не указано иное.
Аднан

3

R , 57 55 байт

Используйте Filterна векторе. Предполагает 32-битные целые числа, поэтому 10 цифр макс.

Угловые случаи: возвращает NULLдля пустого вектора и numeric(0)для вектора без допустимых чисел. Они оба имеют нулевую длину, поэтому должны быть приемлемыми.

-2 благодаря @Giuseppe

Filter(function(n)!sum(n%/%10^(0:10)%%10)^.5%%1,scan())

Попробуйте онлайн!


3

PowerShell , 64 54 байта

$args|?{!([math]::Sqrt(([char[]]"$_"-join'+'|iex))%1)}

Попробуйте онлайн!

-10 байт благодаря маззи

Принимает ввод в качестве аргументов командной строки (см. Примеры ниже), который обрабатывается в массиве PowerShell $args. Мы передаем ?это псевдониму для Where-Object(функции, аналогичные filter), чтобы выбрать наш вывод. Наш выбор основан на вызове .NET, [math]::Sqrt()где цифра-сумма числа является целым числом !(...%1). Целые числа приведут к 0, что, когда noted становится, Trueа нецелые корни становятся False.

Как уже упоминалось в другом месте, «возвращать» пустой массив бессмысленно, поскольку он преобразуется в тот момент, $nullкогда он покидает область видимости, поэтому вывод для пустого ввода - ничто.

Примеры

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1 4 9 16 25 1111
1
4
9
1111

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1431 2 0 22 999999999
1431
0
22
999999999

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 22228 4 113125 22345
22228
4
22345

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1337 4444
4444

1
$n%1проверяет только int$args|?{!([math]::Sqrt(([char[]]"$_"-join'+'|iex))%1)}
mazzy

2

Python 2, 76 байт

lambda l:filter(lambda n:eval(("sum(map(int,`n`))**.5==int("*2)[:-6]+")"),l)

Попробуй это здесь!

Некоторое злоупотребление eval для проверки квадратного числа, отдых довольно не впечатляющий.
Оператор eval оценивает sum(map(int,n ))**.5==int(sum(map(int,n))**.5)


2

Oracle SQL 11.2, 213 байт

WITH v AS(SELECT a,SQRT(XMLQUERY(REGEXP_REPLACE(a,'(\d)','+\1')RETURNING CONTENT).GETNUMBERVAL())s FROM(SELECT TRIM(COLUMN_VALUE)a FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))))SELECT a FROM v WHERE s=CEIL(s);

Un-golfed

WITH v AS
(  
  SELECT a,SQRT(XMLQUERY( 
                   REGEXP_REPLACE(a,'(\d)','+\1')  -- Add a + in front of each digit 
                   RETURNING CONTENT
               ).GETNUMBERVAL())s                  -- Evaluate the expression generated by the added +
  FROM 
  (SELECT TRIM(COLUMN_VALUE)a FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))) -- Split string on ','
)
SELECT a FROM v WHERE s=CEIL(s) -- Is a square if square has no decimal part

2

Брахилог , 26 байт

:1f.
e.(:ef+~^[X:2]h>0;.0)

Пример:

?- run_from_file('code.brachylog',[1431:2:0:22:999999999],Z).
Z = [1431, 0, 22, 999999999]

объяснение

Это ситуация, когда что-то работает слишком хорошо ... ~^[X:2]часть верна как для положительного X, так и для отрицательного , поэтому, чтобы избежать дубликатов, я должен указать это X > 0.

;.0Часть здесь из - за ошибки (перечисление не работает на целое число 0).

  • Главный предикат

    :1f.                Find all values of Input which satisfy predicate 1
    
  • Предикат 1

    e.                  Unify output with an element of the input
    (
      :ef               Find all elements of Output (i.e. all digits)
         +              Sum the digits
          ~^[X:2]       True if that sum is the result of X², whatever X is
                 h>0    Impose that X > 0
    ;                   OR
      .0                True if Output is 0
    )
    

2

Python 2, 53 байта

lambda x:[n for n in x if sum(map(int,`n`))**.5%1==0]

Проверьте это на Ideone .


1
Ибо f([1111111111111111]), похоже, repr(n)содержит 'L'и int('L')бросает ValueError. Я чувствую, что тебе нужно str(n)здесь?
Линн

2
Да, это не будет работать долго Я не думаю, что это отличается от решения в языке с целыми числами фиксированной ширины.
Деннис

2

J, 33 27 байт

6 байт благодаря @miles .

#~[:(=<.)@%:+/"1@(10&#.inv)

В переводчиках онлайн, invне встаёт. Измените это ^:_1вместо.

использование

>> f =: #~[:(=<.)@%:+/"1@(10&#.inv)
>> f 1 4 9 16 25 1111 0
<< 1 4 9 1111 0

Где >>STDIN и <<STDOUT.

Слегка разгульный

to_base_10 =: 10&#.^:_1
sum        =: +/"1
sqrt       =: %:
floor      =: <.
itself     =: ]
equals     =: =
of         =: @
is_integer =: equals floor
test       =: is_integer of sqrt
copies_of  =: #
f =: copies_of~ [: test (sum of to_base_10)

Предыдущая 33-байтовая версия

(]=*:@<.@%:)@(+/"1@(10#.^:_1]))#]

использование

>> f =: (]=*:@<.@%:)@(+/"1@(10#.^:_1]))#]
>> f 1 4 9 16 25 1111 0
<< 1 4 9 1111 0

Где >>STDIN и <<STDOUT.

Слегка разгульный

to_base_10 =: 10#.^:_1]
sum        =: +/"1
sqrt       =: %:
floor      =: <.
square     =: *:
itself     =: ]
equals     =: =
of         =: @
test       =: itself equals square of floor of sqrt
copies_of  =: #
f =: (test of (sum of to_base_10)) copies_of itself

1
Вы можете использовать f&.gдля применения g, затем f, а затем обратное значение gдля сокращения *:@<.@%:до <.&.%:сохранения 2 байтов. Вы можете переставить его и использовать только floor, чтобы получить #~[:(=<.)@%:+/"1@(10&#.inv)27 байтов, где invесть ^:_1, и уже определено.
миль

2

Javascript 66 байт

a=>a.filter(b=>(e=Math.sqrt((b+"").split``.reduce((c,d)=>c-+-d)))==(e|0))

Спасибо за SergioFC за сохранение 7 байтов


Вы не можете просто использовать c+dвместо c-+-d? Кроме того, вы можете использовать n%1==0для проверки, является ли результат целым числом, поэтому, возможно, вы можете сохранить несколько байтов, используя b=>!(Math.sqrt((b+"").split``.reduce((c,d)=>c-+-d))%1)для фильтрации
sergioFC

@sergioFC Я не могу изменить - + - на +, потому что это строки
Балинт

2

Perl 5, 42 байта

41, плюс 1 -peвместо-e

my$s;map$s+=$_,/./g;$_ x=sqrt$s==~~sqrt$s

Объяснение:

  • -pполучает каждое входное целое число в новой строке и присваивает $_этой строке.
  • my$sинициализирует переменную $sв ноль, заново для каждого входного целого числа.
  • map$s+=$_,/./gзахватывает каждый числовой символ и численно добавляет его к $s. (Новая строка становится 0 при нумерации.)
  • sqrt$s==~~sqrt$sпроверяет, $sимеет ли нецелый квадратный корень и $_ x=превращает $_в себя или в пустую строку в зависимости от этого теста.
  • -p печать $_

Спасибо Брэду Гилберту b2gills за сохранение трех байтов.

Также 41 плюс 1:

my$s;s/./$s+=$&/ger;$_ x=sqrt$s==~~sqrt$s
  • s/./$s+=$&/gerдобавляет каждый числовой символ к $s(и символ новой строки равен 0, как указано выше)

2

JavaScript (Node.js) , 48 байт

a=>a.filter(b=>eval([...b+""].join`+`)**.5%1==0)

Попробуйте онлайн!

объяснение

a =>                                  // lambda function taking one argument
    a.filter(                         // filter the list
        eval(                         // begin eval
            [...b+""]                 // convert number to array of digits 
                .join`+`              // join them with + sign
            )                         // close eval. we achieved sum of all digits of number
        **.5                          // square root of number
        %1==0                         // check for perfect square
    )                                 // end filter and return value

1

MATL, 16 14 13 байт

"@tV!UsX^1\?x

Попробуйте онлайн!

объяснение

        % Implicitly grab input
"       % For each number in the input
  @t    % Get this element and duplicate
  V     % Convert to it's string representation
  !     % Transpose the string so each digit is on it's own row
  U     % Convert each row to a number (separates the digits)
  s     % Compute the sum of the digits
  X^    % Compute the square root
  1\    % mod with 1 to determine if the square root is an integer
  ?x    % If there is a remainder, then remove this element from the stack
        % Implicitly display the stack contents

1

Юлия - 38 байт

!X=filter(i->√sum(digits(i))%1==0,X)

Довольно легко увидеть, что это делает. digitsпреобразует число в список его цифр, sumтаким образом, вычисляя сумму цифр, затем получит целое число, если число является квадратом, в противном случае будет дробная часть. %1вернет только дробную часть и, если она равна нулю ( ==0), filterсохранит ее в списке, в противном случае она будет отфильтрована.

Используется как ![22228,4,113125,22345]



1

MATLAB, 52 43 42 байта

@(x)x(~mod(sum(dec2base(x,10)'-48).^.5,1))

Создает анонимную функцию с именем , ansкоторая может быть вызвана с массивом в качестве входных данных: ans([22228,4,113125,22345]).

Демо онлайн . Демонстрация онлайн в Octave, которая не работает для пустого ввода, но MATLAB делает.

объяснение

Мы преобразуем каждый элемент во входном массиве в основание 10, что приведет к двухмерному символьному массиву, где каждая строка содержит цифры числа в массиве. Чтобы преобразовать эти символы в числа, мы вычитаем 48 (ASCII для '0'). Затем мы суммируем по строкам, берем квадратный корень и определяем, является ли каждое значение идеальным квадратом ~mod 1. Затем мы используем это логическое значение для фильтрации входного массива.


1

Clojure, 110 байт

(fn[t](filter(fn[x](let[a(reduce +(*(count(str x))-48)(map int(str x)))](some #(=(* % %)a)(range(inc a)))))t))

Вычисляет сумму цифр числа, а затем отфильтровывает те, для которых не существует числа, квадрат которого равен сумме.

Вы можете увидеть результат здесь - https://ideone.com/ciKOje


1

Perl 6 ,  38   35 байт

{.grep: {($/=sqrt [+] .comb)==$/.Int}}
{.grep: {($/=.comb.sum.sqrt)==$/.Int}}
{.grep: {($/=sqrt [+] .comb)==^$/}}
{.grep: {($/=.comb.sum.sqrt)==^$/}}

Тест:

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
  [1,4,9,16,25,1111] => [1,4,9,1111],
  [1431,2,0,22,999999999] => [1431,0,22,999999999],
  [22228,4,113125,22345] => [22228,4,22345],
  [] => [],
  [421337,99,123456789,1133557799] => [],
);

plan +@tests;

my &sq-digit-sum = {.grep: {($/=sqrt [+] .comb)==^$/}}

for @tests -> $_ ( :key($input), :value($expected) ) {
  is sq-digit-sum($input), $expected, .gist
}
1..5
ok 1 - [1 4 9 16 25 1111] => [1 4 9 1111]
ok 2 - [1431 2 0 22 999999999] => [1431 0 22 999999999]
ok 3 - [22228 4 113125 22345] => [22228 4 22345]
ok 4 - [] => []
ok 5 - [421337 99 123456789 1133557799] => []

1

C 143 141 байт

  • сохранено 2 байта, @ user6188402
i;q(char*n){double m=0;while(*n)m+=*n++-48;m=sqrt(m)-(int)sqrt(m);return !m;}s(n,s)char**n;{i=-1;while(++i<s)if(q(n[i]))printf("%s\n",n[i]);}

Ungolfed попробуйте онлайн

int q(char*n)
{
    double m=0;

    while(*n) // sum digits
        m+=*n++-48;

    // get the decimal part of its square root
    m=sqrt(m)-(int)sqrt(m);

    // true if decimal part is zero
    return !m;
}

// input is text, can be a file
void s(char**n, int s)
{
    int i=-1;

    while(++i<s) // for each number in input
        if(q(n[i])) // if is square
            printf("%s\n",n[i]); // output is terminal
}

1

Сетчатка , 69

Потому что тестирование на идеальные квадраты в сетчатке. Это можно изменить для обобщенного вычисления целочисленного квадратного корня .

. +
$ & $ &
+ `\ Ъ \ д
$ * Б 


\ бб
$ &:
+ `(\ Бб +) :( бб \ 1)
1 $ 2:
G` (: а | 0 $)
. * А

Ввод - это разделенный новой строкой список.

Попробуйте онлайн.

  • Этап 1 - повторите число в каждой строке и разделите a
  • Этап 2 - преобразовать каждую цифру перед aодинарным, выраженным в bs, через пробел
  • Этап 3 - удаление пробелов - каждый унарный теперь представляет собой сумму цифр
  • Этап 4 и 5 - Используйте тот факт, что идеальные квадраты могут быть выражены 1 + 3 + 5 + 7 + .... Разделите каждый одинарный вверх соответственно
  • Этап 6 - grep filter только те, которые точно разбиваются на приведенную выше форму
  • Стадия 7 - отменить все, кроме оригинального номера

У меня было несколько идей, как это улучшить, но в итоге я переписал большую часть. Тем не менее, это по-прежнему именно ваша идея: дублировать ввод, расширять цифры в первой половине, фильтровать квадраты в виде сумм нечетных чисел, отбрасывать первую половину оставшихся строк. Способ, которым я играл в гольф, - через %конфигурацию \Gи прямые ссылки. Не стесняйтесь брать это: retina.tryitonline.net/… :)
Мартин Эндер

1

Python, 50 байт

filter(lambda x:sum(map(int,str(x)))**0.5%1==0,in)

Если n - это список чисел


1
Здравствуйте и добро пожаловать на сайт! Поскольку это соревнование по коду-гольфу , например, кто может написать кратчайший код, мы требуем, чтобы все заявки были как минимум в некотором роде игрой в гольф . У нас есть список питона игры в гольф советы здесь . Вдобавок ко мне, одно очевидное улучшение, которое вы могли бы сделать, это удалить все лишние пробелы и переименовать ваши переменные в одну букву в каждой. Вы также можете использовать входные данные в качестве аргументов функции или STDIN вместо аргументов командной строки.
DJMcMayhem

Также следует указать язык и количество байтов, которое можно подсчитать, например, там .
Никель

1
Добро пожаловать в PPCG! В дополнение к тому, что сказали другие, обратите внимание, что все решения должны быть либо полными программами, либо вызываемыми функциями . До сих пор все ваши ответы были фрагментами, которые предполагают, что входные данные хранятся в некоторой переменной, и просто оценивают результат, что, к сожалению, делает их недействительными. Для получения информации о приемлемых методах ввода / вывода см. Этот мета-пост .
Мартин Эндер


1

K (ок) , 19 17 13 байт

Решение:

(~1!%+/.:'$)#

Попробуйте онлайн!

Объяснение:

(~1!%+/.:'$)# / the solution
(          )# / apply function to list
          $   / convert to string
       .:'    / value (.:) each (')
     +/       / sum
    %         / square-root
  1!          / modulo 1
 ~            / not

Заметки:

  • -2 байта с более умным способом определения квадратов
  • -4 байта благодаря ngn


Я не очень хорошо!
Стритстер

1

MathGolf , 5 4 байта

gÅΣ°

Попробуйте онлайн!

Объяснение:

gÅ    Filter by the next two instructions
  Σ   The digit sum
   °  Is a perfect square?

MathGolf все еще находится в разработке, поэтому я предполагаю, что в ближайшее время появится неявный ввод, чтобы сбрить этот первый байт. Ура!


Поздравляю с первым ответом MathGolf не мной! Я обсуждал скрытый вклад с Эмигной, и он дал мне несколько отличных идей. Надеюсь, скоро.
максимум
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.