Formation carrée approximative


11

Contexte

J'ai un tas de boîtes de forme carrée de taille égale, et comme je suis une personne soignée, je veux les disposer toutes en une formation carrée. Cependant, leur nombre n'est pas nécessairement un carré parfait, donc je devrai peut-être approximer la forme carrée. Je veux que vous me trouviez l'arrangement le plus agréable sur le plan esthétique - par programmation, bien sûr.

Contribution

Votre entrée est un seul entier positif k, représentant le nombre de cases.

Production

Votre programme doit choisir deux entiers positifs m, ntels que ceux-ci sont m*(n-1) < k ≤ m*nvalables. Ils représentent la largeur et la hauteur de la grande forme carrée que nous organisons. Puisque nous recherchons des formes esthétiquement agréables, la quantité doit être minimale, de sorte que la forme soit proche d'un carré et que sa surface soit proche . S'il y a encore plusieurs candidats pour la paire , choisissez celui dont la largeur est maximale.(m - n)2 + (m*n - k)2k(m, n)m

Maintenant, votre sortie réelle ne doit pas être les chiffres met n. Au lieu de cela, vous devez imprimer la disposition des boîtes, en utilisant le caractère #pour représenter une boîte. Plus précisément, vous devez imprimer des n-1lignes, chacune composée de mcaractères #, puis une ligne de k - m*(n-1)caractères #. Notez que la sortie contient exactement des kcaractères #.

Règles et notation

Il ne doit y avoir aucun espace de début ou de fin dans la sortie, sauf que la dernière ligne peut être complétée avec des espaces de fin pour être de longueur m, si vous le souhaitez. Il peut y avoir une nouvelle ligne de fin, mais aucune nouvelle ligne précédente. Vous pouvez utiliser n'importe quel caractère ASCII imprimable à la place de #, si vous le souhaitez.

Vous pouvez écrire un programme complet ou renvoyer une chaîne à partir d'une fonction. Le nombre d'octets le plus bas gagne et les failles standard sont interdites.

Cas de test

Voici les sorties correctes pour quelques valeurs d'entrée.

1
#
2
##
3
##
#
4
##
##
8
###
###
##
13
#####
#####
###
17
######
######
#####
18
#####
#####
#####
###
20
#####
#####
#####
#####
21
######
######
######
###
22
######
######
######
####
23
#####
#####
#####
#####
###

Réponses:


6

Pyth, 28 octets

jbc*\#Qho.a,,N*NJ_/_QN,JQ_SQ

Essayez-le en ligne.

Le nœud est que je trie le potentiel m sur la propriété suivante:

(m - ceil(k/m))^2 + (m*ceil(k/m) - k)^2

Notez l'absence totale de n. La forme totale est définie simplement par m. Ensuite, je transforme à nouveau la propriété ci-dessus, et mon poids de tri final est défini comme la distance euclidienne entre les deux points suivants:

(m, m*ceil(k/m)) and (ceil(k/m), k)

Cela modifie les valeurs de poids, mais pas leur ordre.


3

Python 3, 202 octets

Je sais que c'est plus long que les solutions CJam ou Pyth, mais néanmoins, voici un moyen de résoudre ce problème en Python:

k=int(input())
r,d,s=range(k+1),{},'#'*k
for n in r:
 for m in r:
  if m*n>=k:
   d[m,n]=(m-n)**2+(m*n-k)**2
x,y=max(i for i in d.keys()if d[i]==min(d.values()))
[print(s[i*x:(i*x+x])for i in range(y+1)]

Le principe de base est que nous savons que m et n sont tous deux inférieurs à k. De plus, m * n> = k. Cela signifie que nous pouvons simplement trouver le minimum de l'expression donnée dans le défi pour tout m, n <k, à l'exclusion des valeurs dont le produit est supérieur à k.


En fait, je compte 231 octets dans votre source, pas 234. Mais malgré tout, vous pouvez le réduire en diminuant votre taille de retrait de quatre espaces à un espace. Cela fonctionnera de la même façon.
Alex A.

Il s'agit d'un outil pratique pour obtenir votre nombre d'octets. Au fait, bonne soumission et bienvenue sur le site!
Alex A.

:manquant à la ligne 5. La virgule est ce qui définit un tuple, les crochets ()peuvent être supprimés à la ligne 6. Les espaces entre )et ( ifou for) aussi. maxpeut obtenir le générateur comme paramètre, donc les crochets []sont redondants. Vous parcourez les dclés afin de pouvoir les utiliser en toute sécurité d[i].
Trang Oul

Vous pouvez enregistrer deux octets en changeant (i+1)*xen -~i*xou i*x+x.
Kade

Vous avez un paren supplémentaire non valide à (i*x+x...
FlipTack

2

CJam ( 44 42 octets)

qi_,{)_2$d\/m]_2$-_*@@*2$-_*+~}$W=)'#@*/N*

Démo en ligne

Je m'attendais plutôt à une solution plus simple impliquant des racines carrées, mais ce n'est pas du tout aussi simple. Par exemple, pour la saisie, 31la largeur de la ligne est supérieure de deux au plafond de la racine carrée; pour 273(racine carrée un peu plus de 16,5) le meilleur carré approximatif est un rectangle 21x13 parfait.


1

CJam, 42 octets

li:K_,f-{:XdK\/m]:YX-_*XY*K-_*+}$0='#K*/N*

Essayez-le en ligne

Explication:

li    Get and interpret input.
:K    Store in variable K for later use.
_     Copy.
,     Build sequence [0 .. K-1].
f-    Subtract from K, to get sequence [K .. 1]. Larger values have to come
      first so that they are ahead in ties when we sort later.
{     Begin block for calculation of target function for sort.
  :X    Store width in variable X.
  d     Convert to double.
  K\/   Calculate K/X.
  m]    Ceiling.
  :Y    Store height in variable Y.
  X-    Calculate Y-X.
  _*    Square it.
  XY*   Calculate X*Y...
  K-    ... and X*Y-K
  _*    Square it.
  +     Add the two squares.
}$    Sort by target function value.
0=    Get first element, this is the best width.
'#K*  Build string of K '# characters.
/     Split using width.
N*    Join with newlines.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.