Це сферичне число?


29

Сфенічне число - це число, що є добутком рівно трьох відмінків. Перші кілька сферичних чисел є 30, 42, 66, 70, 78, 102, 105, 110, 114. Це послідовність A007304 в OEIS.

Ваше завдання:

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

Вхід:

Ціле число між 0 і 10 ^ 9, яке може бути або не бути сферичним числом.

Вихід:

Корекційне / хибне значення, що вказує, чи є вхідним сферичним числом.

Приклади:

30  -> true
121 -> false
231 -> true
154 -> true
4   -> false
402 -> true
79  -> false
0   -> false
60  -> false
64  -> false
8   -> false
210 -> false

Оцінка:

Це , найкоротший код у виграші байтів.


Чи 60є сфенічне число? 2 × 2 × 3 × 5
Ерік Аутгольфер

1
@EriktheOutgolfer це не продукт 3-х різних прайменів, але це продукт 3-х чітких і 1-х дублікальних простих.
Rɪᴋᴇʀ

1
@Riker Я не дуже впевнений, чи означає "3 різних праймес" означає "3 прими, які всі чітко виражені" або "коли уніфіковані повинні залишитися 3 праймери". EDIT: О, я бачу, 60це не сферичне число. (чекає роз'яснення ОП)
Ерік Атголфер

@EriktheOutgolfer Відповідно до визначення сферичних чисел, 60 не є одним із них. Але я не знаю, чи справді 60 справжніх для цього виклику.
Пшеничний майстер

@WheatWizard, 60 не є сферичним числом (наприклад, помилка виводу / повернення).
Грифон - Відновити Моніку

Відповіді:


7

Брахілог , 6 3 байти

ḋ≠Ṫ

Спробуйте в Інтернеті!

Пояснення

ḋ        The prime factorization of the Input…
 ≠       …is a list of distinct elements…
  Ṫ      …and there are 3 elements

2
І тоді є одна мова, яка має вбудований тип .
Ерік Аутгольфер

І вбудований також.
Zacharý

1
@ Zacharý насправді не є вбудованим присудком; це вбудована змінна: список з 3 змінних елементів. Це досить корисна заздалегідь обмежена змінна у багатьох різних викликах.
Фаталізувати

Вітаємо з найкоротшою відповіддю.
Грифон - Відновіть Моніку

11

баш, 43 байти

factor $1|awk '{print $2-$3&&$3-$4&&NF==4}'

Спробуйте в Інтернеті!

Введіть через аргумент командного рядка, виводить 0або 1викреслити.

Досить зрозуміло; аналізує вихідні дані, factorщоб перевірити, що перший і другий фактори різні, другий і третій різні (вони є в упорядкованому порядку, тому цього достатньо), і є чотири поля (число вводу та три фактори).


11

MATL , 7 байт

_YF7BX=

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

_YF   % Implicit input. Nonzero exponents of prime-factor decomposition
7     % Push 7
B     % Convert to binary: gives [1 1 1] 
X=    % Is equal? Implicit display

@Suever Я думав про це, але тоді фальшивий вихід стає потворнішим (або порожнім з помилкою, або масивом з деякими нулями). Не впевнений, чи варто мені ...
Луїс Мендо

4
X=це найсумніше вбудоване, що я коли-небудь бачив.
Ерік Аутгольфер

9

C, 88 78 126 58 77 73 + 4 ( lm) = 77 байт

l,j;a(i){for(l=1,j=0;l++<i;fmod(1.*i/l,l)?i%l?:(i/=l,j++):(j=9));l=i==1&&j==3;}

Ungolfed прокоментував пояснення:

look, div; //K&R style variable declaration. Useful. Mmm.

a ( num ) { // K&R style function and argument definitions.

  for (
    look = 1, div = 0; // initiate the loop variables.
    look++ < num;) // do this for every number less than the argument:

      if (fmod(1.0 * num / look, look))
      // if num/look can't be divided by look:

        if( !(num % look) ) // if num can divide look
          num /= look, div++; // divide num by look, increment dividers
      else div = 9;
      // if num/look can still divide look
      // then the number's dividers aren't unique.
      // increment dividers number by a lot to return false.

  // l=j==3;
  // if the function has no return statement, most CPUs return the value
  // in the register that holds the last assignment. This is equivalent to this:
  return (div == 3);
  // this function return true if the unique divider count is 3
}

Спробуйте в Інтернеті!


1
Розгляньте i*1.0/lзамість акторів плавати. (А оскільки l, jє глобальними , вони не започатковано 0 безкоштовно, вам не потрібно робити, якщо функція викликається тільки один раз не впевнений , що це правило для цього ..)
Mat


5

CJam , 11 байт

rimFz1=7Yb=

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

На основі моєї відповіді MATL.

ri    e# Read integer
mF    e# Factorization with exponents. Gives a list of [factor exponent] lists
z     e# Zip into a list of factors and a list of exponents
1=    e# Get second element: list of exponents
7     e# Push 7
Yb    e# Convert to binary: gives list [1 1 1]
=     e# Are the two lists equal? Implicitly display


4

Лушпиння , 6 байт

≡ḋ3Ẋ≠p

Спробуйте в Інтернеті!

Повертає 1 для сферичних чисел, а 0 - інакше.

Пояснення

≡ḋ3Ẋ≠p    Example input: 30
     p    Prime factors: [2,3,5]
   Ẋ≠     List of absolute differences: [1,2]
≡         Is it congruent to...       ?
 ḋ3           the binary digits of 3: [1,1]

В останньому уривку конгруентність між двома списками означає однакову довжину та однаковий розподіл правдоподібних / хибних значень. У цьому випадку ми перевіряємо, що наш результат складається з двох правдивих (тобто ненульових) значень.


4

Математика, 31 байт

SquareFreeQ@#&&PrimeOmega@#==3&

Оскільки ви вже тестуєте на Squarefree-ness, це PrimeNuбуде так само добре PrimeOmega, і коротше.
Марк С.





2

J , 15 байт

7&(=2#.~:@q:)~*

Спробуйте в Інтернеті!

Пояснення

7&(=2#.~:@q:)~*  Input: integer n
              *  Sign(n)
7&(         )~   Execute this Sign(n) times on n
                 If Sign(n) = 0, this returns 0
          q:       Prime factors of n
       ~:@         Nub sieve of prime factors
    2#.            Convert from base 2
   =               Test if equal to 7

Дуже приємно використовувати ~: і #. Альтернативою може бути (7 & (= #. @ ~: @Q:) ~ *), яку мені здається трохи легше читати, але не коротше.
боб




2

C, 91 102 байт, виправлений (знову), гольф і перевірений реально на цей раз:

<strike>s(c){p,f,d;for(p=2,f=d=0;p<c&&!d;){if(c%p==0){c/=p;++f;if(c%p==0)d=1;}++p;}c==p&&f==2&&!d;}</strike>
s(c){int p,f,d;for(p=2,f=d=0;p<c&&!d;){if(c%p==0){c/=p;++f;if(c%p==0)d=1;}++p;}return c==p&&f==2&&!d;}

/ * Це також працює в 93 байтах, але оскільки я забув про стандартні правила, що забороняють тип int за замовчуванням на динамічних змінних, та про неприпустиме неявне повернення значень без призначення, я не збираюся його приймати:

p,f,d;s(c){for(p=2,f=d=0;p<c&&!d;){if(c%p==0){c/=p;++f;if(c%p==0)d=1;}++p;}p=c==p&&f==2&&!d;}

(Хто сказав, що я щось знаю про С? ;-)

Ось тестовий кадр із скриптом оболонки в коментарях:

/* betseg's program for sphenic numbers from 
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h> /* compile with -lm */

/* l,j;a(i){for(l=1,j=0;l<i;i%++l?:(i/=l,j++));l=i==1&&j==3;} */
#if defined GOLFED
l,j;a(i){for(l=1,j=0;l++<i;fmod((float)i/l,l)?i%l?:(i/=l,j++):(j=9));l=i==1&&j==3;}
#else 
int looker, jcount;
int a( intval ) {
  for( looker = 1, jcount = 0; 
    looker++ < intval; 
    /* Watch odd intvals and even lookers, as well. */
    fmod( (float)intval/looker, looker )  
      ? intval % looker /* remainder? */
        ? 0 /* dummy value */
        : ( inval /= looker, jcount++ /* reduce the parameter, count factors */ ) 
      : ( jcount = 9 /* kill the count */ ) 
  )
    /* empty loop */;
  looker = intval == 1 && jcount == 3; /* reusue looker for implicit return value */
}
#endif

/* for (( i=0; $i < 100; i = $i + 1 )) ; do echo -n at $i; ./sphenic $i ; done */

Я запозичив попередню відповідь betseg, щоб перейти до своєї версії.

Це моя версія алгоритму betseg, яку я взяв на голову, щоб дійти до свого рішення:

/* betseg's repaired program for sphenic numbers
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int sphenic( int candidate )
{
  int probe, found, dups;
  for( probe = 2, found = dups = 0; probe < candidate && !dups; /* empty update */ ) 
  { 
    int remainder = candidate % probe;
    if ( remainder == 0 ) 
    {
      candidate /= probe;
      ++found;
      if ( ( candidate % probe ) == 0 )
        dups = 1;
    }
    ++probe;
  } 
  return ( candidate == probe ) && ( found == 2 ) && !dups;
}

int main( int argc, char * argv[] ) { /* Make it command-line callable: */
  int parameter;
  if ( ( argc > 1 ) 
       && ( ( parameter = (int) strtoul( argv[ 1 ], NULL, 0 ) ) < ULONG_MAX ) ) {
    puts( sphenic( parameter ) ? "true" : "false" );
  }
  return EXIT_SUCCESS; 
}

/* for (( i=0; $i < 100; i = $i + 1 )) ; do echo -n at $i; ./sphenic $i ; done */

Чи відповідає це на питання зараз?
Joel Rees

Так. Вставте це посилання на відповідь betseg в: [betseg's answer](https://codegolf.stackexchange.com/a/135203/65836). Ви також можете натиснути редагувати його відповідь, щоб запропонувати його змінити, якщо ви хочете, це включало б пояснення - жодних обіцянок щодо того, буде затверджено чи ні.
Стівен

Зараз я тут, і я виправив свою програму, вона зараз на 87 байт; але ваша програма теж виглядає добре.
betseg

@betseg Цікаво, що ви цього разу використовували плаваючу крапку. О, і дякую, що дозволили мені запозичити ваш алгоритм. ;-)
Джоел Різ

@JoelRees я додав пояснення до своєї відповіді, також у вашій відповіді є проблема, на яку я думаю? схоже, це не працює правильно: Спробуйте це онлайн
betseg


1

Javascript (ES6), 87 байт

n=>(a=(p=i=>i>n?[]:n%i?p(i+1):[i,...p(i,n/=i)])(2)).length==3&&a.every((n,i)=>n^a[i+1])

Приклад фрагмента коду:

f=
n=>(a=(p=i=>i>n?[]:n%i?p(i+1):[i,...p(i,n/=i)])(2)).length==3&&a.every((n,i)=>n^a[i+1])

for(k=0;k<10;k++){
  v=[30,121,231,154,4,402,79,0,60,64][k]
  console.log(`f(${v}) = ${f(v)}`)
}


1

Пітон 2 , 135 121 байт

  • Досить довго, оскільки це включає всі процедури: прайм-перевірку, коефіцієнти отримання простих частот та стан номера номера сфери.
lambda x:(lambda t:len(t)>2and t[0]*t[1]*t[2]==x)([i for i in range(2,x)if x%i<1and i>1and all(i%j for j in range(2,i))])

Спробуйте в Інтернеті!



1

J, 23 байти

0:`((~.-:]*.3=#)@q:)@.*

Спробуйте в Інтернеті!

Обробка 8 і 0 в основному зруйнувала цей ...

q: дає всі основні фактори, але не справляється з 0. Останнє говорить просто: "унікальні фактори повинні дорівнювати факторам" і "кількість їх повинна бути 3"


Це не вдається ввести інформацію60
Conor O'Brien

@ ConorO'Brien спасибі Перегляньте мою редагування - виправлення 60 допомогло , але я зрозумів, що я також не працював 0 правильно, а обробляю, що більше ніж в два рази перевищує байт
Jonah

Останнє було моєю оригінальною ідеєю, і це не вдається 8.
Conor O'Brien

У мене є (6=]#@,~.)@q:можливе рішення
Conor O'Brien

@ ConorO'Brien ах хороший пункт про 8. ваш не вдасться до 0, хоча.
Йона

1

Japt , 14 байт

k
k@è¥X ÉÃl ¥3

Спробуйте в Інтернеті!


@Oliver Це призведе до передачі функції Number.k(), яка не матиме ефекту, і просто перевірте, чи вхід має 3 прості коефіцієнти, а не 3 чіткі прості фактори. Це означатиме 8(з трьома основними факторами 2, 2, 2) : пройде, не дивлячись на те, що він не був у A007304
Justin Mariner

Ах, ти маєш рацію. Я просто збирався на тестові справи.
Олівер

@Oliver Так, це справді кинуло мене на цикл під час роботи над цим рішенням. Я просто додав 8до тестових випадків з цієї причини.
Джастін Марінер


1

VB.NET (.NET 4.5), 104 байти

Function A(n)
For i=2To n
If n Mod i=0Then
A+=1
n\=i
End If
If n Mod i=0Then A=4
Next
A=A=3
End Function

Я використовую функцію VB, де ім'я функції також є змінною. Після закінчення виконання, оскільки немає зворотного оператора, він замість цього передасть значення 'функції'.

Останнє A=A=3можна придуматиreturn (A == 3) на мовах на основі С.

Починається в 2 і ітераційно знімає праймери. Оскільки я починаю з найменших праймес, його не можна розділити на складене число.

Спробуємо вдруге розділити на той самий прайм. Якщо це так (наприклад, як 60 ділиться двічі на 2), він встановить кількість простих чисел на 4 (вище максимального, дозволеного для сферичного числа).

Спробуйте в Інтернеті!


1

Діалог APL, 51 49 48 46 45 43 байт

1∊((w=×/)∧⊢≡∪)¨(⊢∘.,∘.,⍨){⍵/⍨2=≢∪⍵∨⍳⍵}¨⍳w←⎕

Спробуйте в Інтернеті!(змінено, щоб він міг працювати на TryAPL)

Я хотів подати той, який взагалі не покладається на простір імен dfns, навіть якщо він довгий .


1

J, 15 14 19 байт

Попередня спроба: 3&(=#@~.@q:)~*

Поточна версія: (*/*3=#)@~:@q: ::0:

Як це працює:

(*/*3=#)@~:@q: ::0:  Input: integer n
               ::0:  n=0 creates domain error in q:, error catch returns 0
            q:       Prime factors of n
         ~:@         Nub sieve of prime factors 1 for first occurrence 0 for second
(*/*3=#)@            Number of prime factors is equal to 3, times the product across the nub sieve (product is 0 if there is a repeated factor or number of factors is not 3)

Це стосується випадків 0, 8 та 60, яких не було в попередній версії.


1
чому б не 3 = # ~ .q: для 7 символів? З сесії J 3 = # ~ .q: 30 ==> 1 і 3 = # ~ .q: 20 ==> 0
Річард Донован

Річард, Ваша пропозиція дає хибний позитив для n = 60 і створює помилку домену для n = 0, але моя попередня версія також не вдалася для n = 60. Ваш коментар спонукав мене до прагнення до правильного рішення!
боб

0

Математика, 66 57 байт

Length@#1==3&&And@@EqualTo[1]/@#2&@@(FactorInteger@#)&

Визначає анонімну функцію.

є Транспонування .

Пояснення

FactorIntegerдає перелік пар факторів та їхніх показників. Напр FactorInteger[2250]=={{2,1},{3,2},{5,3}}. Це транспонується для зручності використання і подається на функцію Length@#1==3&&And@@EqualTo[1]/@#2&. У першій частині Length@#1==3перевіряється наявність 3 унікальних факторів, а друга - у And@@EqualTo[1]/@#2всіх показниках.


0

PHP, 66 байт:

for($p=($n=$a=$argn)**3;--$n;)$a%$n?:$p/=$n+!++$c;echo$c==7&$p==1;

Запустіть як трубу -nRабо спробуйте в Інтернеті .

Нескінченна петля для 0; вставити, $n&&перш ніж --$nвиправити.

зламатися

for($p=($n=$a=$argn)**3;    # $p = argument**3
    --$n;)                  # loop $n from argument-1
    $a%$n?:                     # if $n divides argument
        $p/=$n                      # then divide $p by $n
        +!++$c;                     # and increment divisor count
echo$c==7&$p==1;            # if divisor count is 7 and $p is 1, argument is sphenic

приклад
аргумент = 30:
прості коефіцієнти є 2, 3а 5
інші дільники - 12 * 3 = 6, 2 * 5 = 10і 3 * 5 = 15
їх добуток: 1*2*3*5*6*10*15є 27000==30**3


0

Python 99 байт

def s(n):a,k=2,0;exec('k+=1-bool(n%a)\nwhile not n%a:n/=a;k+=10**9\na+=1\n'*n);return k==3*10**9+3

Перше подання. Пробачте, якщо я зробив щось не так. Ніби нерозумно, підраховує кількість факторів n, а потім кількість разівn ділиться на кожного (додаючи 10 ** 9).

Я впевнений, що є кілька простих способів відрізати ~ 10-20 символів, але я цього не зробив.

Також це нерозривно повільно при 10 ** 9. Можна зробити все добре , змінивши '...a+=1\n'*nна'...a+=1\n'*n**.5 , оскільки нам потрібно лише перейти до квадратного кореня n.

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