La torre si bilancerà?


36

introduzione

Data una torre ASCII e la forza del vento, scrivi un programma o una funzione per determinare se la torre si bilancerà o in che modo cadrà.

Ad esempio la prima torre si bilancia ma la seconda cade verso sinistra.

  # #            # #
  ###            ### 
 ###            ### 
 # #            # # 
#####          ##### 
 ###            ### 
 ###              #

Questa è la mia prima sfida. Spero che vi piaccia.

Indicazioni

La torre è costituita da blocchi collegati rappresentati da #e forma un oggetto rigido . Ogni blocco è un quadrato con una larghezza e altezza di un'unità e ha una densità costante. Ci sono due forze che agiscono sulla torre, il suo peso e la forza del vento. Tutte le forze agiscono su ciascun blocco individualmente e passano attraverso il centro del blocco.

  • A causa del suo peso, ogni blocco ha una forza verso il basso di un'unità che agisce su di esso.
  • Inoltre, ogni blocco che non ha un altro blocco adiacente ad esso sul suo lato sopravento ha una forza che agisce orizzontalmente nella direzione del vento. L'entità di questa forza è data come input.
  • La direzione del vento è indicata da una bandiera ASCII da qualche parte nell'input. Ci sarà una bandiera nell'input se e solo se il vento non è zero. La bandiera non influenza nessuna forza.

La bandiera apparirà esattamente come appare sotto.

Flag design and corresponding wind direction:

 o~~        ~~o
 |~~        ~~|

--->        <---

Per chiarire, la torre è un oggetto solido e non si romperà e non è attaccato al suolo. Tuttavia, il programma dovrebbe calcolare le forze per ciascun blocco singolarmente per determinare se la torre si bilancia.

Esempio

  o~~
  |~~
  # #              > > 
  ###              >## 
 ###              >##  
 # #              > >  
#####            >#### 
 ###              >##  
 ###              >##  

Wind force: 1    Wind direction: --->

Il vento soffia a destra e spingerà sui blocchi mostrati con a >in alto a destra. Si noti che il vento agisce all'interno dei fori.

Supponiamo che l'angolo inferiore sinistro della torre abbia coordinate (0,0). Il momento attorno alla base sinistra della torre (0,0)è di 71 unità in senso orario, quindi la torre non cadrà a sinistra. Il momento attorno alla base destra della torre a (0,3) è di 8 unità in senso orario, quindi la torre cadrà a destra.

Se il vento stesse soffiando verso sinistra, i rispettivi momenti sarebbero 2 unità in senso orario e 61 unità in senso antiorario negli stessi punti, quindi la torre si bilancerebbe.

Ingresso

  • Il programma o la funzione deve accettare due input, un numero decimale e una stringa separata da nuova riga.
  • Il numero decimale sarà maggiore di zero e rappresenta la forza esercitata dal vento su ciascun blocco esposto come nell'esempio.
  • La stringa rappresenterà la torre dall'alto verso il basso e può contenere spazi, #|o~caratteri e newline. Puoi facoltativamente assumere una nuova riga finale e / o riempire la torre con spazi finali per formare un rettangolo.
  • La torre ne avrà almeno una #nella fila inferiore.
  • È possibile inserire il numero e la stringa in entrambi gli ordini.
  • Se l'entità della forza del vento è diversa da zero, ci sarà una bandiera da qualche parte nell'ingresso, a terra o collegata alla torre. La bandiera avrà la forma esatta mostrata sopra.
  • I #blocchi formeranno una forma connessa che può contenere buchi. In altre parole, tutti i blocchi saranno adiacenti a un altro blocco a meno che non vi sia un solo blocco.

Produzione

  • Uno dei personaggi B, Lo R, a seconda del bilanciamento della torre, cade verso sinistra (in senso antiorario) o verso destra (in senso orario).
  • L'output può avere una nuova riga finale opzionale.

Questo è ; si applicano regole standard e scappatoie.

B Casi test:

Wind: 1
    ~~o
    ~~|
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0
##
# ##
###

Wind: 1.7
o~~
|~~
#
##

Wind: 0.768
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0.1
#
#
#
#
#
# o~~
# |~~

Wind: 0
#

Wind: 0
############

Wind: 144
               o~~
############   |~~

Wind: 0
#######
 ##
 #
 ##

Wind: 0
                ############
           ############
       ############
    ############
   ############
 ############
############

Wind: 41
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

L Casi test:

Wind: 0
#####
   #


Wind: 42
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

Wind: 4
########
    ###
 ~~o# ##
 ~~|#  #

Wind: 3
########
    ###
 o~~# ##
 |~~   #

R Casi test:

Wind: 1
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 2
o~~
|~~
#

Wind: 0.001
                 ############
            ############
        ############
     ############
    ############
  ############     o~~
 ############      |~~

Wind: 145
               o~~
############   |~~

Wind: 1
#
#
#
#
#
# o~~
# |~~

Wind: 0.26
#######
 ##
 #   o~~
 ##  |~~

Soluzione di riferimento (JavaScript)

Provalo online.

function balanced(tower, wind) {
    var rows = tower.split('\n').reverse(); // Reverse so row index matches height of row.
    var height = rows.length;
    var leftEdge = rows[0].indexOf('#'); // Find bottom left corner of tower.
    var rightEdge = rows[0].lastIndexOf('#') + 1; // Find bottom right corner of tower.
    var leftMoment = 0, rightMoment = 0; // Moments around the bottoms corners of tower.
    wind *= tower.indexOf('~o')>-1 ? -1 : 1; // Find direction of the wind.

    // Sum the moments for each block in the tower.
    for (var i = height - 1; i >= 0; i--) {
        rows[i].split('').map(function(ch, index, arr) {
            if (ch=='#') {
                // If there's not a block toward the windward side of the current one.
                if ((wind < 0 && arr[index-1] != '#') || (wind > 0 && arr[index+1]!='#')) {
                    // Add moments from wind.
                    leftMoment += (i+0.5)*-wind;
                    rightMoment += (i+0.5)*-wind; 
                }

                leftMoment += leftEdge - (index + 0.5);
                rightMoment += rightEdge - (index + 0.5);
            }
        }, 0);
    }
    if (leftMoment > 0) return 'L';
    else if (rightMoment < 0) return 'R';
    else return 'B';
}

Classifica

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

# Perl, 43 + 2 (-p flag) = 45 bytes

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


17
Benvenuti in PPCG; questa è una prima sfida scritta in modo eccellente! :)
Maniglia della porta

Risposte:


2

JavaScript (ES6), 239 byte

Ho sminuito la mia implementazione di riferimento. Sono stato in grado di salvare byte modificando il ciclo for in a map, usando &&e ||cortocircuendo le istruzioni if, e usando l' ,operatore per adattare tutto su un'istruzione in modo da evitare un ritorno esplicito nella funzione.

(a,b)=>((c=a.split`
`.reverse(),d=c[f=g=0].indexOf`#`,e=c[0].lastIndexOf`#`+1),a.match`o~`&&(b*=-1),c.map((h,i)=>h.replace(/#/g,(j,k,l)=>(b>0&l[k-1]!='#'|b<0&l[k+1]!='#'&&(f+=(i+=0.5)*b,g+=i*b),f+=d-k-0.5,g+=e-k-0.5))),f>0?'L':g<0?'R':'B')

Potrebbe essere ancora possibile giocare a golf di più. Suggerimenti sono ben accetti


+1 molto meglio della mia soluzione ingenua
Conor O'Brien,

1

JavaScript ES6, 297 293 byte

Fondamentalmente una versione compressa dell'implementazione data.

b=(n,e)=>{r=n.split`
`.reverse(),t=r.length,a=r[0].indexOf`#`,f=r[i=l=0].lastIndexOf`#`+1;e*=n.indexOf`~o`>-1?-1:1;for(d=t-1;d>=0;d--)r[d].split``.map((n,r,t)=>{(j="#")==n&&((0>e&&j!=t[r-1]||e>0&&j!=t[r+1])&&(i+=(d+.5)*-e,l+=(d+.5)*-e),i+=a-(r+.5),l+=f-(r+.5))},0);return i>0?"L":0>l?"R":"B"}

Semiespanso:

b = (n, e) => {
    r = n.split `
`.reverse(), t = r.length, a = r[0].indexOf `#`, f = r[i = l = 0].lastIndexOf `#` + 1;
    e *= n.indexOf `~o` > -1 ? -1 : 1;
    for (d = t - 1; d >= 0; d--) r[d].split ``.map((n, r, t) => {
        (j = "#") == n && ((0 > e && j != t[r - 1] || e > 0 && j != t[r + 1]) && (i += (d + .5) * -e, l += (d + .5) * -e), i += a - (r + .5), l += f - (r + .5))
    }, 0);
    return i > 0 ? "L" : 0 > l ? "R" : "B"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.