Bâtiments visibles

15

Ce puzzle est dérivé du puzzle "Cœur de la ville" de CodinGame SamSi.

La description

Vous décidez de vous promener dans une ville de tuiles n* net allez à la tuile centrale. Tous les bâtiments sont infiniment petits, mais vous avez une super vision et vous pouvez tout voir de près et de loin.

Contraintes

n est toujours bizarre

Vous pouvez voir n'importe quel bâtiment qui n'est pas directement obstrué par un autre

Tâche

Marquez chaque bâtiment visible avec *. Le bâtiment est visible s'il n'est pas bloqué par un autre bâtiment sur la même ligne de vision.

En d'autres termes, si @est l'origine, le bâtiment est visible si la coordonnée x et la coordonnée y sont co-amorcées l'une avec l'autre.

Exemple d'entrée et de sortie

Contribution:

7

Production:

 ** **
* * * *
*******
  *@*
*******
* * * *
 ** **

*est un bâtiment visible, est un bâtiment invisible, et @c'est là que vous êtes.

Notation

Rappelez-vous, c'est le , donc la réponse avec le moins d'octets l'emporte.

var QUESTION_ID=91394,OVERRIDE_USER=59057;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}*{font-family:"Helvetica",sans-serif}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Soren
la source
Pouvez-vous préciser comment la sortie est générée?
Leaky Nun
Je pense que ce sera bien d'avoir un exemple où l'entrée est beaucoup plus grande que 5, car la sortie pour 5 n'est pas particulièrement illustrative
Sp3000
Sommes-nous toujours au centre? Qu'en est-il lorsque l'entrée est uniforme?
Leaky Nun
1
@LeakyNun "n is always odd"
Sp3000
@LeakyNun La sortie peut être générée comme vous le souhaitez, mais elle doit suivre les spécifications de sortie. Suis-je correct avec l'entrée / sortie 7x7?
Soren

Réponses:

8

Excel-VBA, (47 * n ^ 2) octets et 121 octets

Instruction:

Excel s'avère être très pratique pour ce défi et il existe une combinaison de formules Excel pour obtenir le modèle exact comme les OP affichés pour une entrée donnée. Heureusement pour moi, Excel a une fonction GCD - une formule intégrée pour renvoyer le plus grand diviseur commun d'entiers positifs, donc je n'ai pas à en créer un en utilisant l' algorithme euclidien . Pourquoi ai-je besoin d'une fonction GCD ici? C'est parce que deux nombres sont appelés coprime, si leur plus grand diviseur commun est égal à 1 . Les nombres ici sont les coordonnées de la position xet y, par rapport à l'origine @,. Voici la formule Excel

=IF(GCD(ABS(COLUMN()-m),ABS(m-ROW()))=1,"*","")

mest le nom d'une cellule de référence et est égal au plus petit entier supérieur ou égal à n/2, plafond ( n/2), où nest le nom d'une cellule de référence pour l'entrée. Collez cette formule dans la cellule A1, puis faites glisser toute la plage avec la taille n x n. La longueur de la formule est de 47 octets mais vous devez la répliquer n x nfois, elle est donc égale à (47 * n ^ 2) octets.

Pour automatiser le processus et réduire l'utilisation de caractères, nous pouvons utiliser VBA car il est intégré à Excel. Tout d'abord, définissez une feuille de calcul Excel comme suit:

entrez la description de l'image ici

Mettez ensuite le code suivant dans la fenêtre Exécution

n=[A1]:m=Int(n/2)+1:Range("A1",Cells(n,n))="=IF(GCD(ABS(COLUMN()-"&m &"),ABS("&m &"-ROW()))=1,""*"","""")":Cells(m,m)="@"

Déverrouillé le code:

Sub A()
    n = [A1]
    m = Int(n / 2) + 1
    Range("A1", Cells(n, n)) = "=IF(GCD(ABS(COLUMN()-" & m & "),ABS(" & m & "-ROW()))=1,""*"" ,"""")"
    Cells(m, m) = "@"
End Sub

Explication:

  1. n = [A1] : Définissez n comme entrée et affectez la valeur de la cellule A1 à n.
  2. m = Int(n / 2) + 1: Façon personnalisée de renvoyer la même sortie que la fonction de plafond pour l'argument n/2.
  3. Range("A1", Cells(n, n)) = "=IF(GCD(ABS(COLUMN()-" & m & "),ABS(" & m & "-ROW()))=1,""*"" ,"""")": Collez la formule ci-dessus dans chaque cellule de la plage dont la taille n x ncommence à la cellule A1.
  4. Cells(m, m) = "@" : Attribuez le centre de la plage à un caractère @.

Production:

La figure ci-dessous est l'exemple de sortie pour l'entrée n = 11

entrez la description de l'image ici

J'ai défini la couleur de la police sur rouge pour la rendre plus attrayante. Encore mieux

entrez la description de l'image ici

Anastasiya-Romanova 秀
la source
Pourquoi "collez" la formule dans chaque cellule au lieu de la calculer directement dans la fonction VBA?
Vale
@Vale Parce que ce sera plus long car je dois utiliser une instruction de bouclage, une instruction IF, WorksheetFunction, etc.
Anastasiya-Romanova
mais dans votre décompte d'octets, vous mettez 47 * n ^ 2 ...?
Vale
@Vale Vous n'avez peut-être pas lu ceci: " La longueur de la formule est de 47 octets mais vous devez la répliquer n x nfois, donc elle est égale à (47 * n ^ 2) octets " dans ma réponse. Voir également la discussion dans la section commentaire de la réponse d'Ugoren . J'espère que cela rend la chose plus claire.
Anastasiya-Romanova
@ Anastasiya-Romanova 秀 selon la convention, le nombre d'octets correct pour cette solution serait 121 bytesque seul le programme lui-même contribue au nombre d'octets. Dans le cas que vous avez référencé, la source doit être copiée et collée dans chaque cellule individuelle, alors que dans votre solution, tout se fait par programmation.
Taylor Scott
4

Gelée , 16 octets

:2ạḶgþ`«2ị“* @”Y

Essayez-le en ligne!

Comment ça fonctionne

:2ạḶgþ`«2ị“* @”Y  Main link. Argument: 2n + 1

:2                Perform integer division by 2, yielding n.
   Ḷ              Yield [0, ..., 2n].
 ạ                Take the absolute difference of the result to both sides.
                  This yields A := [n, ... 0, ... n].
      `           Call the quicklink to the left with left and right argument A.
     þ              Table; call the link to the left for all x in A and all y in A.
    g                 Yield the GCD of x and y.
       «2         Truncate the GCD at 2, leaving 0 for the origin, 1 for coprime
                  coordinates, and 2 otherwise.
         ị“* @”   Index into that string, mapping [1, 2, 0] to ['*', ' ', '@'].
               Y  Join, separating by linefeeds.
Dennis
la source
Pouvez-vous ajouter une vue développée et commentée du code?
Soren
Je l'ai déjà fait. Manque-t-il quelque chose?
Dennis
Je ne le voyais pas pour une raison quelconque ... ça a l'air bien maintenant!
Soren
3

Perl 6 , 77 ou 74 octets

Programme complet (77 octets) :

my \h=Int(get/2);say |map {$_|$^j??2>$j gcd$_??'*'!!' '!!'@'},-h..h for -h..h

( essayez-le en ligne )

S'il est acceptable de renvoyer la sortie d'un lambda sous forme de liste de listes de chaînes à 1 caractère (74 octets) :

{my \h=$_ div 2;map {map {$^i|$_??2>$i gcd$_??'*'!!' '!!'@'},-h..h},-h..h}

( essayez-le en ligne )

smls
la source
3

SILOS , 236 octets

GOTO s
funcg
if q p
r=p
return
lblp
t=p
t%q
p=q
q=t
GOSUB g
return
lbls
readIO
m=i
m/2
a=i
lbla
a-1
a-m
b=i
lblb
b-1
b-m
p=a
p|
q=b
q|
GOSUB g
r-1
A=r
A|
r/A
r*-1
r+1
p=r
r*r
r*6
p*4
r+p
r+32
printChar r
b+m
if b b
printLine 
a+m
if a a

Essayez-le en ligne!

Port de ma réponse en C .

Leaky Nun
la source
la sortie pour 15 est intéressante
Rohan Jhunjhunwala
3

C, 147 145 135 133 133 octets

2 octets grâce à Dennis.

10 octets grâce à Arnauld.

2 octets grâce à H Walters.

r,m,i,j;g(a,b){r=b?g(b,a%b):a;}main(n){scanf("%d",&n);for(m=n/2,i=-m;i<=m;putchar(r?r*r-1?32:42:64),i+=++j%n<1&&puts(""))g(i,j%n-m);}

Ideone it!

Les conseils de golf sont les bienvenus comme toujours.

Leaky Nun
la source
Si vous définissez une autre variable globale (disons x) et faites x=au lieu de returndans la g()fonction, alors je pense que vous pouvez faire {g(i,j-m);putchar(x?x*x-1?32:42:64);}et économiser 7 octets. (Ou 8 octets si vous supprimez également le saut de ligne. Est-ce vraiment nécessaire?)
Arnauld
@Arnauld Merci, mise à jour
Leaky Nun
Hmm. Vous n'avez pas besoin de déclarer m,i,jdeux fois, n'est-ce pas ?
Arnauld
@Arnauld Apparemment, je suis un idiot.
Leaky Nun
1
Passez ++jà ++j%n(+2 octets) et j-mà j%n-m(+2 octets). Ensuite, vous pouvez supprimer ,j%=n(-5 octets).
H Walters du
3

Javascript (ES6), 114 113 105 octets

Cela a commencé comme un portage de la version C de Leaky Nun et a ensuite été optimisé. La plupart des optimisations sont spécifiques à JS.

n=>(r=j=>i<n?('*@*'[1+(g=(i,j)=>j?g(j,i%j):i)(i-m,j-m)]||' ')+(++j<n?'':(i++,`
`))+r(j%n):'')(i=0,m=n>>1)

Exemple:

let f =
n=>(r=j=>i<n?('*@*'[1+(g=(i,j)=>j?g(j,i%j):i)(i-m,j-m)]||' ')+(++j<n?'':(i++,`
`))+r(j%n):'')(i=0,m=n>>1)

console.log(f(7))

Arnauld
la source
2

Pyth, 40 octets

L@"@* "hS[b2)jsMcQyM.aMiM*.**2[r_/Q2h/Q2

Je suis très nouveau sur Pyth, donc cela peut probablement être approfondi.

Essayez-le en ligne

Comment ça fonctionne

L@"@* "hS[b2)jsMcQyM.aMiM*.**2[r_/Q2h/Q2   

L@"@* "hS[b2)                              Lambda y. Input: b
L                                          Declare lambda
         [b2)                              List [b, 2]
        S                                  Sort ascending
       h                                   Head. Yield first element a, clamping to max 2
  "@* "                                    String literal "@* "
 @                                         Index into string with a, yielding string[a]

             jsMcQyM.aMiM*.**2[r_/Q2h/Q2   Program. Input: Q
                                _/Q2 /Q2   -Q//2 and Q//2
                                    h      Head. Q//2+1
                               r           Range [-Q//2, Q//2+1]
                              [            List
                            *2             Duplicate
                          .*               Splat. Unpack
                         *                 Cartesian product. Yield all coordinate pairs
                       iM                  Map GCD over above
                    .aM                    Map absolute value over above
                  yM                       Map y over above, yielding required characters
                cQ                         Chunk. Split above into Q pieces
              sM                           Map concatenate over above
             j                             Join on newlines
                                           Implicitly print
TheBikingViking
la source
2

GolfScript, 98 83 octets

~:l.2/~):o:i;{o{.abs i abs.!!{{.@\%.}do}*;1={'*'}{' '}if\.i|!{\;'@'\}*)}l*;i):i;n}*

Essayez-le en ligne!

Entrée = 11

 **** **** 
* * * * * *
** ** ** **
* * * * * *
***********
    *@*    
***********
* * * * * *
** ** ** **
* * * * * *
 **** **** 
FedeWar
la source