Calcular el cuadrado de un entero con restricciones [cerrado]


8

El rompecabezas

Debe escribir un programa o función p (n) que devuelva el cuadrado de lo que se ingresó y puede suponer que la entrada es un número entero no negativo. En términos más simples, devuelve n 2 .

Reglas

  1. No está permitido usar *o /(o cualquier otro operador de energía o de raíz cuadrada, como POWo SQRT, si su idioma contiene tales funciones)
  2. No puede usar un bucle, o usar construcciones que sean similares a un bucle. Ejemplo de bucle como construcciones son GOTOy recursividad.

Ejemplo

Function p(n)
Dim r()
ReDim r(n)
p = Len(Join(r, Space(n)))
End Function

Sea creativo y (ab) use las funciones y características que le da su idioma de elección.

*editar

Las estructuras tipo bucle son bucles que le permiten repetir 1 o más instrucciones.

-si pudieras agregar un stdout "1"código a tu código y terminarías repitiendo esa salida n veces, contará como un bucle


1
@dwana ¿No son la segunda parte de la primera regla y la tercera regla las mismas?
Def

14
Esto no debería haber sido reabierto, porque todavía carece de claridad sobre lo que cuenta como "bucle". Por ejemplo, ¿qué pasa con los pliegues?
Peter Taylor

55
@PeterTaylor o mapas para el caso.
Martin Ender

77
@dwana ¿Puede ser específico sobre estas cosas en sus reglas: (1) ¿Están permitidas las funciones integradas que tienen inherentemente bucles, como mapas, iteradores, pliegues, reducciones, etc.? (2) ¿Se permite evaluar la cadena como un código usando eval / exec?
Optimizador

44
Esto es en gran parte un duplicado de un desafío codegolf anterior, que pedía el más general en m*nlugar de n*nusar el *. Ver codegolf.stackexchange.com/a/18283/14485
Mark Lakata

Respuestas:


42

CJam, se pone sus lentes

q~33c

(*_*)

(*_")>⌐■-■

(⌐■_■)

"]sG>4%,)

Entrada a través de STDIN

Prueba el código aquí

Tenga *en cuenta que en el código no se usa como multiplicador, sino como operador de unión

También tenga en cuenta que la parte interesante del código no es solo una cadena, sino que la mitad es el código involucrado en la búsqueda del cuadrado. Entonces ... TRATE CON ÉL

Esto te ayudará a lidiar con esto:

q~33c                    "Read the number and put ASCII character 33 on stack with it"
(                        "Decrease it to get ASCII code 32 character, which is a space";
 *_                      "Repeat the space input number times and make another copy";
   *                     "Put that many spaces in between each space. Now we have";
    )                    "n*n spaces string. We take out the last space out of it";
(                        "Decrement the space to get ASCII 31 character";
 *                       "Fill the n*n - 1 spaces with that to get 2*n*n - 3";
  _                      "string. Then copy it again.";
   ")>⌐■-■               "Put the sun glasses in";
(⌐■_■)                   "Wear the sun glasses. Be cool.";
"]s                      "Add everything to a single string of 4*n*n - 6 + 16"
   G>                    "length. Remove first 16 characters";
     4%                  "Take every 4th character from that string to get n*n - 1"
       ,)                "length string. Take length and increment to get n*n";

20

Rubí

def square(n)
  case n
  when 0..1
    n
  when 2..36
    '100'.to_i(n)
  else
    raise RangeError, 'Integer overflow!'
  end
end

10
Esto es realmente inteligente.
Ypnypn

3
Para el registro, en Mathematica esto funciona muy enteros arbitrarios (incluyendo 0 y negativo), sin tener que manejar los casos especialmente: FromDigits[{1, 0, 0}, Input[]]. Lo mismo en CJam:4Ybl~b
Martin Ender

20

APL? ∊⍵⍵

{+/ ∊⍵⍵ ⍴1}

Esta respuesta está dedicada a todas aquellas personas que dicen "∊⍵⍵" cada vez que ven los símbolos APL :-)

Ejemplos

      {+/∊⍵⍵⍴1} 3
9
      {+/∊⍵⍵⍴1}¨⍳20
1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400

Explicación

{       }   This function takes a number ⍵,
{   ⍵⍵⍴1}   builds a matrix of ⍵ by ⍵ all filled with ones,
{+/∊    }   and sums all its elements together.

3
eww ... <! - marcador de posición ->
Kroltan

44
¿No está sumando todos los elementos de una matriz de pseudo bucle? El resumen se realiza a través de reducir o doblar, ambos están en bucle
Optimizer

+/en otros idiomas se llama sum()y veo muchas respuestas usándolo. Por el mismo razonamiento que no podrías usar *en CJam.
Tobia

Veo su punto, pero unirse no requiere leer el valor de todos y cada uno de los elementos, por lo que puede hacerse sin un bucle en un nivel bajo. Sumar los elementos de la matriz realmente necesita iterar sobre todos los elementos para agregar. Alternativamente, puede hacer algo como aplanar la matriz y obtener su longitud.
Optimizador

2
¿Parece el símbolo de un jamón prensado?
FreeAsInBeer

15

Abusar de algunas funciones en Mathematica

El doble del área de un triángulo rectángulo isósceles

a =RegionMeasure@SASTriangle[n,ArcSin[1], n] 
a+a

El área de un cuadrado. ¡Por supuesto!

RegionMeasure[Rectangle[{0, 0}, {n, n}]]

La misma idea, en una forma diferente:

Integrate[n, {x, 0, n}]  (* thx to DigitalTrauma *)

El número de elementos en una matriz cuadrada:

 Length[Flatten[Normal[AdjacencyMatrix[RandomGraph[{n, RandomInteger[n]}]]]]]

o

 Plus@@Flatten[ConstantArray[1, {n, n}]]

o

 Length@Flatten[Outer[f,Range[n],Range[n]]]

o

 Length[Distribute[p[Range[n],Range[n]],List]]

etc ...


1
Otro k[n_] := Integrate[n, {x, 0, n}]:?
Trauma digital el

DigitalTrauma, Integratemuy agradable pero itera, lo que creo que es una forma de bucle.
DavidC

Es cierto, aunque creo que es solo un bucle implícito. Por el mismo argumento que afirmaría Areay los amigos son la multiplicación implícita (pero también permitió)
Digital Trauma


12

Mathematica

Otra respuesta usando algunas características divertidas de Mathematica

n = Input[];
g = EdgeCount@CompleteGraph@n;
g + g + n

Un gráfico completo con nvértices tiene binom(n,2) = n(n-1)/2aristas (que también es el enésimo número triangular). Entonces, el resultado es simplemente el doble, más la entrada.


1
Muy inteligente, usando gráficos.
DavidC

12

Python 2

Puramente matemático, evitando cualquiera de las operaciones prohibidas:

import cmath
n=input()
if n:
  l=complex(0, -cmath.log(n) - cmath.log(n))
  print int(round(abs(complex(cmath.cos(l),cmath.sin(l)))))
else:
  print 0

Este es el exp(ln(x)*y)truco habitual adaptado a este problema:

  • Como y es 2, entonces simplemente podemos hacer ln(x)+ln(x)para deshacernos de la multiplicación.
  • Sentí que math.exp()era un poco demasiado cerca de la prohibida "POW" por el juego limpio, así que en vez todo el asunto se convierte en compleja y la identidad de Euler se utiliza para reemplazar el exp()con cos()ysin()
  • Para evitar las situaciones en las que ise necesita multiplicación / división explícita por , complex()se utiliza la función en su lugar.

2
Si cambias math.loga cmath.logpuedes manejar números negativos. Tampoco es necesario import mathentonces.
FryAmTheEggman

inputno hace lo que piensas en Python 2, y en Python 3 printes una función en lugar de una declaración.
Cristian Ciupitu

@CristianCiupitu ¿Qué creo que inputhace en Python 2? ;-). Ciertamente escribiría esto de manera diferente si fuera a ser un código de producción, pero para los propósitos de este desafío está bien, siempre que la entrada sea una expresión numérica bien formada. Entiendo que hay una evaluación implícita allí, y su potencial maldad.
Trauma digital

8

Pure Bash

No hay bucles explícitos o aritméticos:

(($1))||{ echo 0;exit;}
eval a=({1..$1}{1..$1})
echo ${#a[@]}

Utiliza las expansiones bash para crear dos listas 1-n y las expande entre paréntesis y muestra el tamaño de la matriz resultante.


Método similar, pero haciendo uso de coreutils en su lugar:

join <(seq -f "1 %g" $1) <(seq -f "1 %g" $1) | wc -l

8

R, deliciosa ineficiencia con Monte Carlo

La expectativa E[x]para la parametrización de forma / escala de la Distribución Gamma es shape*scale.

No veo meanser prohibido, así que aquí está la solución de muestra conmean()

f = function(n, k = 1e9){round((mean(rgamma(k, shape = n, scale = n))))}
f(99) 

Sin usar mean(), es posible usar mode[x], que es igual a (shape-1)*scale, pero esto implica escribir una add.onefunción para omitir y +1luego escribir otra Modefunción para tabular el modo.

add.one = function(x) length(c(seq(x),NA))
Mode = function(x) (u<-unique(x))[which.max(tabulate(match(x,u)))]
f.mode = function(n, k = 1e9){Mode(round(rgamma(k, shape = add.one(n), scale = n)))

La precisión no está garantizada, pero la ley de gran número debería entrar en vigencia para 1,000,000,000 de muestras, lo que me ha dado los resultados correctos para todos mis casos de prueba.


Estaba pensando en un truco similar, +1
shadowtalker

7

Java

Primera entrada, ¿es así como funciona?

int g(int n){
    int[] a = new int[n];
    Arrays.fill(a,n);
    return IntStream.of(a).sum();       
}

... no es divertido u_u

6

C#

Crea una cadena con n caracteres y luego reemplaza cada carácter con la cadena de n caracteres. Esto produce una cadena con una longitud de n * n.

using System;

public class Test
{
    public static void Main()
    {
        int n = Int32.Parse(Console.ReadLine());
        String s = "".PadLeft(n, 'X');
        Console.WriteLine(s.Replace("X", s).Length);
    }
}

Pruébelo aquí: http://ideone.com/lubIFg .


2
Eso es creativo!
TheNumberOne

5

Matlab

una advertencia: esto se basa principalmente en matemáticas, así que no esperes código fuente elegante

Tenga en cuenta que a = n^2iff log(a) = log(n)*2iff log(log(a)) = log(log(n))+log(2). Entonces, esta función es solo encontrar el cero de la función f(a) = log(log(n))+log(2) - log(log(a))que obviamente está en a = n^2.

function s = g(n)
    f = @(a) log(log(n))+log(2)-log(log(a));
    s = fnzeros(f);
end

Aquí algunas otras funciones no muy creativas:

Aquí el programa sumará el número 1+2+3+...+n = 1/2 * (n^2+n)dos veces y restará n, por lo que el resultado es siempren^2

g=@(n)sum(1:n)+sum(1:n)-n

Esta función crea una n x nmatriz de números aleatorios (entre 0 y 1) y luego devuelve el número de elementos.

g=@(n)numel(rand(n));

La siguiente función crea una matriz vandermonde del vector (0,0,n)y genera la entrada que consiste enn^2

function s = g(n)
    a = vander([0,0,n]);
    s = a(3,1)
end

Esta función crea el inverso de una matriz hilbert de tamaño ndonde el elemento superior izquierdo siempre están^2

function s = g(n)
    a = invhilb(n);
    s = a(1);
end

Anuncio n. ° 3: Por supuesto, en aplicaciones de la vida real se usaría g=@(n)nnz(nan(n));por razones de eficiencia y brevedad. ;-)
knedlsepp

Cuando se trata de eficiencia Creo que el cálculo de la inversa de la matriz de Hilbert de forma explícita será más eficiente: function s = g(n); a = inv(hilb(n)); s = a(1); end. Pero, de nuevo, su solución es más corta; P
error

5

C

sizeof(char[n][n])

Funciona hasta INT_MAX en tiempo constante y sin asignación de memoria.

Ejemplo:

#include <stdio.h>
#include <limits.h>
int main(){
    for( int n=0 ; n<10 ; n++ ){
        printf("%d: %ld\n", n, sizeof(char[n][n]));
    }
    int n = INT_MAX;
    printf("%d: %ld\n", n, sizeof(char[n][n]));
}

muestra

0: 0
1: 1
2: 4
3: 9
4: 16
5: 25
6: 36
7: 49
8: 64
9: 81
2147483647: 4611686014132420609

tal vez haga obvio que el bucle es solo un contenedor para mostrar el programa ejecutándose en múltiples valores
masterX244

4

Java

Esta es la primera respuesta que realmente no usa bucles o recursividad.

int square(int n){
    if (n > 0){
        n = -n;
    }
    return m(n,0) + m(n,1) + m(n,2) + m(n,3) + m(n,4) + m(n,5) + m(n,6) + m(n,7) + m(n,8) + m(n,9) + m(n,10) +
            m(n,11) + m(n,12) + m(n,13) + m(n,14) + m(n,15) + m(n,16) + m(n,17) + m(n,18) + m(n,19) + m(n,20) +
            m(n,21) + m(n,22) + m(n,23) + m(n,24) + m(n,25) + m(n,26) + m(n,27) + m(n,28) + m(n,29) + m(n,30) + m(n,31);
}

int m(int number, int index){
    if (number >> index << 31 >>> 31 == 0){
        return 0;
    } else {
        return number << index;
    }
}

@FlorianF Todas las demás respuestas llaman funciones que usan bucles. Hasta donde sé, llamar a una función 32 veces y luego agregar los resultados no cuenta como usar bucles. Si he añadido el comunicado System.out.print(1)que m, el programa imprimirá 1exactamente 32 veces, no n veces.
TheNumberOne

3

GolfScript

Histocrat ha mostrado una forma de usar la conversión de base: aquí hay otra.

{.,1base.++}:p;

Disección

{       # Function boilerplate
  .     # Duplicate the input. Stack: x x
  ,     # Turn the second one into an array [0 1 ... x-1]
  1base # Sum the elements of the array. Stack: x x(x-1)/2
  .+    # Double. Stack: x x(x-1)
  +     # Add. Stack: x*x
}:p;    # Question asks for the function to be called p
        # The fact that this destroys the built-in p is unfortunate, but required

2

Emacs Lisp

(defmacro square-it (n)
  (cons '+ (make-list n n)))

(square-it 11) ;; => 121

Una macro simple que se expande (square-it 5)en (+ 5 5 5 5 5). Por supuesto, la entrada debe ser una constante de tiempo de compilación.


2

Javascript

function square(i) {
    return new Array(++i).join(new Array(i).join(' ')).length;
}

2

Haskell

Hay muchas posibilidades si [x..y]se permiten rangos , algunos de ellos son:

f n|x<-sum[1..n]=x+x-n
f n=sum$take n[n,n..]
f n=length$[1..n]>>[1..n]
f n=sum$[1..n]>>[1..n]>>[1]

Los dos últimos usan la instancia Monad de listas. para listas xs, ysretenciones que xs>>ysse ysagregan a sí mismas length xsveces.

otro truco es solo

import Data.Monoid
f x=x<>x

esta función, cuando se le da un argumento 'apropiado' (que por supuesto son de la clase de tipo Num) devuelve su cuadrado. Product 3 :: Num a => Product aes un ejemplo de tal argumento.

Básicamente, esta función cuando se aplica Product a, (que en la Numclase iff aestá en i) mappends sí mismo y devuelve Product (a*a).

si somos más estrictos sobre qué es un número / en qué números debería funcionar nuestra función, podemos definir fcomo

import Data.Monoid
f n|x<-Product n=getProduct$x<>x

2

Java

Esto es demasiado largo para poner en la respuesta, pero básicamente una de las líneas de código ocurre una cantidad de veces aproximadamente igual al sqrt de Integer.MAX_VALUE(que es 46340). :RE

Sin comentarios ni saltos de línea, el código escrito sería de 1.112.155 caracteres.

int s(int n){
    if(n==0|n==1)return n;
    int c=2,r=n+n;
    if(n==c++)return r;r+=n;
    if(n==c++)return r;r+=n;
    if(n==c++)return r;r+=n;
    if(n==c++)return r;r+=n;
    if(n==c++)return r;r+=n;
    if(n==c++)return r;r+=n;
                            //... (same line of code a total of 46336 times)
    if(n==c++)return r;r+=n;
    if(n==c++)return r;
    return n==c?r+n:r+n+n; //r = 46340^2
}

2

R

Esta función se basa en contar todas las combinaciones posibles de dos secuencias que van del 1 al n. El valor 0 se trata por separado.

f <- function(n) if (n) nrow(expand.grid(s <- seq(n), s)) else 0

2

Clojure

(def squares (lazy-cat [0] (map (fn [sq x] (+ sq x x 1)) squares (range))))

Secuencia infinita de todos los cuadrados a partir de 0. La función:

(defn square [n] (nth squares n))

1

J

Un poco de arte ascii ...

p =. ( $ @,@  ( ($*) ([-])"*/ ($*) ))


1

SQL (PostGIS)

Haciendo uso del área y haciendo funciones de envolvente en la extensión PostGIS a PostGreSQL para crear una geometría cuadrada y devolver su área. Podría cambiarse para devolver el cuadrado de carrozas también.

CREATE FUNCTION square(n int)RETURNS int AS $$
BEGIN 
    RETURN ST_Area(ST_MakeEnvelope(0,0,n,n));
END;
$$LANGUAGE plpgsql;

En uso;

SELECT square(150);

Square Integer
--------------
22500

1

Pitón

Utiliza matemáticas simples. Basado en la suma de una progresión aritmética.

s=lambda n:(sum(range(n))<<1)+n

Explicación:

a = sum(range(n)) # sum of arithmetic progression from 1 to n-1:  n*(n-1)/2
b = a<<1          # bitshift left by 1 (multiply by 2):  n*n - n
c = b+n           # add n:  n*n

Aunque la suma y el rango probablemente contienen bucles implícitos,
pero según la especificación de la pregunta, no hay forma de insertar una declaración de impresión aquí para que se repita, así que ... :)


1

Golpetazo

yes|xargs -L$1|xargs -L$1|head -n1|iconv -futf16|wc -m

Solo funciona si n <256.


1

PHP

function square($v) {
    return array_sum(array_fill(0, $v, $v));
}

funciona con un entero en el rango [0; 46340]

Editar: acabo de ver el código @thebestone y es básicamente el mismo


1

Perl

$_=<>;chop;s/./$_/g;print

el programa espera que el número de entrada se cuadre en forma unaria (es decir, base 1). La salida también es unaria. Simplemente reemplaza cada dígito con el número entero.

Ejemplo de uso:

perl -e '$_=<>;chop;s/./$_/g;print'
000                                   # <- user input
000000000                             # <- output

1

Scala:

scala> val q = (n:Int) =>(List.fill (n)(n)).sum
q: Int => Int = <function1>

scala> q(9)
res21: Int = 81

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.