Numérotation des chambres d'hôtel


42

Étant donné l'entrée d'un "hôtel" dans l'art ASCII avec une seule pièce marquée, indiquez le numéro de la pièce selon certaines règles.

Voici un exemple d'hôtel ASCII:

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

Voici quelques informations supplémentaires sur les hôtels ASCII:

  • Chaque "bâtiment" est représenté par un rectangle de #caractères, où chacun #représente une "pièce".

  • L'hôtel ci-dessus se compose de trois bâtiments. Chaque bâtiment est séparé par deux colonnes d'espaces, et le "plancher" le plus bas sera toujours sur la dernière ligne.

  • Chaque bâtiment aura toujours de 1 à 9 "étages" (rangées) et 1 à 9 "chambres" à chaque étage. Il y aura aussi toujours 1 à 9 bâtiments.

  • Les chambres sont numérotées comme suit: [building #][floor #][room on floor #]. Par exemple, marquons quelques pièces dans le dessin ci-dessus:

                   ##
                   ##
    #####          ##
    #####  ####$#  ##
    ##%##  ######  ##
    #####  ######  #@
    

    La pièce marquée avec %est la chambre 123 (bâtiment 1, étage 2, 3ème chambre étage). De même, la pièce marquée avec $est la pièce 235 et la @pièce 312.

  • Les bâtiments, les étages et les "nièmes chambres sur le sol" sont toujours indexés.

L'entrée consistera en un hôtel ASCII avec une chambre simple remplacée par un astérisque ( *). C'est la pièce pour laquelle vous devez entrer le numéro de la pièce. L'entrée doit être considérée comme une chaîne unique, mais vous pouvez utiliser des virgules comme séparateurs de ligne au lieu de nouvelles lignes (dans le cas où la langue de votre choix ne peut pas utiliser une entrée multiligne ou si elle est plus courte pour une entrée ligne unique). Vous pouvez éventuellement exiger une virgule de fin / nouvelle ligne. Vous pouvez également ajouter des lignes avec des espaces pour que l'entrée soit un rectangle complet.

Puisqu'il s'agit de , le code le plus court en octets gagne.

Cas de test (contenus dans un seul bloc de code pour préserver l’espace vertical):

Input:
*

Output: 111

Input:
#  #  *  #  #

Output: 311

Input:
#####
#####
####*
#####
#####

Output: 135

Input:
         #####
         #####           ######
         #####           ######
#  #  #  #####  #  #  #  ######  *

Output: 911

Input:
#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
#  #  ##  ###  ##*##  ########
#  #  ##  ###  #####  ########

Output: 523

Input:
           #
           *
           #
           #
           #
           #
           #
           #
#########  #  #

Output: 281

Input:
                        ########*
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
#  #  #  #  #  #  #  #  #########

Output: 999

1
Y aura-t-il un jour une entrée complètement vide
Downgoat

@ Doᴡɴɢᴏᴀᴛ Il y aura toujours un astérisque quelque part, alors non.
Poignée de porte


5
Sérieusement: il peut être utile d'ajouter que vos bâtiments sont toujours de forme rectangulaire (n'est-ce pas?)
agtoever

1
@agtoever Non, il doit s'agir d'une seule chaîne, comme indiqué dans la question.
Poignée de porte

Réponses:


11

CJam, 34 à 31 octets

qN/W%zSf-La%{_{s'*&}#_)@@=}3*;\

Cela nécessite que l'entrée soit complétée en un rectangle avec des espaces.

Essayez-le en ligne! Vous pouvez également exécuter tous les cas de test.

Explication

qN/      e# Read input and split into lines.
W%z      e# Rotate 90° counter-clockwise.
Sf-      e# Remove all spaces from the rows.
La%      e# Split into buildings. We've now got a 3D array of rooms, where the first
         e# dimension is the building, the second the room number and the third is the
         e# the floor number.
{        e# Run this block three times. At each stage it will find the index of the "*"
         e# along the current dimension and leave the element at that index on the stack
         e# for the next round...
  _      e#   Duplicate the current array.
  {      e#   Find the index of the first element where this block yields something
         e#   truthy...
    s    e#     Flatten into a single string.
    '*&  e#     Set intersection with "*".
  }#
  _)     e#   Duplicate the index and increment it, because the results should be 1-based.
  @@=    e#   Pull up the array and the other copy of the index and select the
         e#   corresponding element.
}3*
;\       e# We've now got the building, room and floor index on the stack, as well as the
         e# "*" character itself. We discard the character and swap the room and the floor
         e# floor number. When the three indices are printed back-to-back at the end of
         e# the program, that will yield the desired result.

9

Pyth, 34 octets

LxKh/#\*b\*jkhM[//<hJ_.zyJd2xJKycK

Manifestation

Cela utilise une astuce de golf que je n’ai jamais utilisée auparavant: Assigner à une variable ( K) dans une fonction ( y) pour enregistrer un résultat partiel de cette fonction.

Explication:

LxKh/#\*b\*jkhM[//<hJ_.zyJd2xJKycK
L                                     Define y(b):      (b is a list of strigs)
    /#\*b                             Filter b for strings containing '*'
   h                                  Take the first such string
  K                                   Store it in K
 x       \*                           And return the index of '*' in that string.
                      .z              Take the input as a list of strings
                     _                Reverse it (bottom to top)
                    J                 Store in J
                   h                  Take the bottommost row
                        yJ            Find y(J). This is the index in whichever
                                      row of J has the * of the *. Also store
                                      that row in K.
                  <                   Slice J up to that index.
                 /        d           Count the number of spaces
                /          2          Divide by 2. This is the building number.
                            xJK       Take the index in J of K. This is the floor.
                                cK    Chop K on whitespace.
                               y      Find the index in whatever element of K has
                                      the * of the *. This is the room number.
                                      This also overwrites K, but we don't care.
               [                      Gather the above into a list.
             hM                       Convert 0-indexing to 1-indexing.
           jk                         Concatenate. Print implicitly.

9

JavaScript (ES6), 142 136 octets

h=>h.split`
`.reverse(r=0).map((t,i,l)=>r?0:(f=i+1,b=1,l[o=0].slice(0,r=t.indexOf`*`+1).replace(/  /g,(_,s)=>o=++b&&s+2),r-=o))&&[b]+f+r

6 octets sauvegardés grâce à @nderscore !

Explication

h=>
  h.split`
`                            // get each line of the input string
  .reverse(                  // reverse the lines to make getting the ground floor easy
    r=0)                     // initialise r to 0
  .map((t,i,l)=>             // for each line of the reversed input string
    r?0:(                    // if the marked room has not been found yet:
      f=i+1,                 // f = floor number
      b=1,                   // b = building number, default to 1
      l[o=0].slice(0,        // get the substring of 0 to the marked room, default o to 0
        r=t.indexOf`*`+1)    // r = absolute index of room + 1 (or 0 if not found)
      .replace(/  /g,(_,s)=> // count the spaces between buildings
        o=++b&&s+2),         // increment b, o = index of marked room's building
      r-=o                   // make r relative to the room's building
    )
  )
  &&[b]+f+r                  // output the result ([b] casts b to a string)

Tester


Certaines économies d'octets (-6): .map((t,i,l)=>, slice(0,r=t.indexOf`*`+1), o=++b&&s+2,[b]+f+r
nderscore

@nderscore Merci, j'aime beaucoup le [b]+f+rconseil!
user81655

7

awk, 70

!i{i=index($0,"*")}i{$0=substr($0,0,i);f++}END{print NF f length($NF)}

Exemple:

Input:
#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
#  #  ##  ###  ##*##  ########
#  #  ##  ###  #####  ########

While no * was found, do nothing.
#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
A * is found in column 14. From now on, truncate and increment the floor counter.
#  #  ##  ###  ##*    f=1
#  #  ##  ###  ###    f=2
Awk automatically splits $0 into space separated fields, counted by builtin NR.
In the end, NR and f hold hotel and floor number.
The room number is the length of the last hotel.

6

C, 131 130 119 113 octets

b,f,i,j=111;main(c){for(;c=~getchar();)c&32?f+=10,b=i=0:++i<j?c%3?f=j,j=i:c&2?b+=50-b%50:++b:0;printf("%d",b+f);}

Prend une entrée sur stdin; l'entrée ne doit pas avoir de fin de ligne. Suppose le complément de 2.

Ungolfed:

// Declare variables (default type is int) and initialize, by default to 0:
b,    // Building number (multiplied by 100, 0-based) + room number (0-based)
f,    // Floor (111-based, multiplied by 10)
i,    // Current column of input character within line (1-based)
j = 111; // Column of asterisk character once found (1-based), 111 before then
main (c)    // Declare main function and variable c to hold input character
{
  for (;    // Loop on input
    c = ~getchar();  // Read a character into c, bitwise inverted to break
                     // EOF (numeric value -1). This means that following 
                     // operations (on the ASCII value of the input) are 
                     // also inverted.
    )
    c & 32 ?              // Newline?
      f += 10, b = i = 0 :  // Increment floor; reset building, room, column
      ++i < j ?             // Increment column; before asterisk, or asterisk not yet found?
        c % 3 ?               // Asterisk character?
          f = j, j = i :        // Reset floor and record column
          c & 2 ?               // Space character?
            b += 50 - b % 50 :    // Increment building and reset room
            ++b :                 // Otherwise, # character; increment room
        0;                    // After asterisk; do nothing
  printf("%d", b + f);  // Write out results
}

Je suis sûr que cette astuce doit être beaucoup utilisée dans le golf, mais je n’ai jamais vu de programme qui utilise la stdio, même si elle est incluse!
Dave

@Dave une paire de parens vides n'est qu'un gâchis d'expression potentielle, et les en-têtes sont un luxe :) Vous avez également volé une ou deux de vos idées pour le gâcher.
ecatmur

Agréable. J'aime l'incrément de bâtiment - enregistre 3 octets supplémentaires. J'ai repris cette idée et réussi à faire correspondre votre nouveau compte, mais je ne peux pas l'améliorer davantage.
Dave

4

Stackgoat , 73 bytes [non-concurrent]

Stackgoat est un langage en pile qui n'a rien à voir avec les chèvres.

y'#ZGDYZG'*iVXsV@"\\*"ZGN2/1+y'#ZG' ZG'q:Nq'*i-yXsq'*i@"[#*]+"M0M1-@'*i1+

C'est un langage assez nouveau, alors laissez-moi savoir s'il y a un problème. Je me suis donné tout un mal à la tête pour comprendre cela, donc c'est à peu près autant que je joue au golf.

Explication

Ce programme a 3 parties pour chaque 3 chiffres du numéro de chambre

y'#ZG    // Remove all # from input
D        // Duplicate
YZG      // Remove all spaces
'*i      // Index of *
V        // Reverse stack
Xs       // Split on spaces
V@       // Unreverse, item at *'s index
"\\*"ZG  // Remove all *s
N        // Get length
2/1+     // Divide by 2, add 1

y'#ZG    // Remove all #
' ZG     // Remove all spaces
'q:      // Store in q
N        // Get length
q'*i     // *'s index in q
-        // Subtracted from length

yXs      // Split on newlines
q'*i     // Get index of * in q
@        // Get indexed-th line
"[#*]+"M // Match all buildings
0M       // Get *'s building no.
1-       // Subtract one
@        // nth building at right line
'*i      // *'s index
1+       // Added to one


6
Cela semble utiliser deux nouvelles fonctionnalités implémentées après la publication du défi. La réponse est donc sans compétition.
Poignée de porte

Par curiosité, @Doorknob - où cette règle est-elle définie? J'ai essayé de chercher dans tous les endroits logiques, mais je n'ai rien trouvé à ce sujet ...
Alex


4

Ruby, 103

->n{r=x=b=0
n.lines{|s|(t=s=~/\*/)&&(x=t;r=($`.reverse+' ')=~/ /)
r+=10;b=s[0..x].count" "}
b*50+r+101}

Programme non testé

g=->n{
  r=x=b=0
  n.lines{|s|                  #for each line in n
    (t=s=~/\*/)&&              #if the line contains an asterisk
      (x=t                     #record its position in x. $` is a special variable containing the part of the string to the left of the last match made.
      r=($`.reverse+' ')=~/ /) #reverse $` and search for the index of the first space to find room number (before the search a space is appended in case it is 1st building.)
    r+=10                      #increment r by 10 for the floor number (obviously this will have been reset to the row ith the asterisk by the previous line)
    b=s[0..x].count" "}        #count the number of spaces left of x in the current row to find building number (loop will exit with calc from bottom row, which is the correct one.) 
b*50+r+101}                    #multiply number of spaces by 50 to get 1st digit, add r for 2nd and 3rd digit. Then add 101 to correct 1st and 3rd digits from 0-indexed to 1-indexed.

puts g["
*"]



puts g["
#  #  *  #  #"]


puts g["
#####
#####
####*
#####
#####"]

puts g["
         #####
         #####           ######
         #####           ######
#  #  #  #####  #  #  #  ######  *"]



puts g["
#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
#  #  ##  ###  ##*##  ########
#  #  ##  ###  #####  ########"]




puts g["
           #
           *
           #
           #
           #
           #
           #
           #
#########  #  #"]



puts g["
                        ########*
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
#  #  #  #  #  #  #  #  #########"]

J'aime beaucoup l'utilisation intelligente de $`celui-ci.
Poignée de porte

4

JavaScript (ES6), 121

x=>x.split`
`.reverse().map((r,f,h,a=r.indexOf`*`)=>x=~a?(h=h[0].slice(0,a).split`  `).length+[f+1]+-~h.pop().length:x)|x

Moins joué au golf et expliqué

H=x=>x.split`\n` // split in lines
  .reverse() // reverse, so we can scan bottom up
  .map( (r,f,h) => // exectute for each line
         // r is the current row
         // f in the row index, so that f+1 is the floor number
         // h is the reversed array, h[0] is the bottom floor
       ~(a=r.indexOf`*`) // a is the position of '*' in the line, if found - else 0
       && ( // if a >= 0
         h = h[0]        // bottom floor line 
             .slice(0,a) // ... truncated at position of '*'
             .split`  `, // ... and splitted at '  ', as an array
         x = h.length  // the array len is the building number
             + [f+1]   // floor number, using [] to force string concatenation
             + -~ h.pop().length // the length of the last array element is the number 
                                 // of chars in the block before '*'
                                 // increment by 1 to get the room number
      )
  )
  && x // return the found value

TESTER

H=x=>x.split`
`.reverse().map((r,f,h,a=r.indexOf`*`)=>x=~a?(h=h[0].slice(0,a).split`  `).length+[f+1]+-~h.pop().length:x)|x

// test
console.log=x=>O.textContent+=x+'\n';

;[['*',111],['#  #  *  #  #',311],
[`#####
#####
####*
#####
#####`,135],
[`         #####
         #####           ######
         #####           ######
#  #  #  #####  #  #  #  ######  *`,911],
[`#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
#  #  ##  ###  ##*##  ########
#  #  ##  ###  #####  ########`,523],
[`           #
           *
           #
           #
           #
           #
           #
           #
#########  #  #`,281],
[`                        ########*
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
#  #  #  #  #  #  #  #  #########`,999]]  
.forEach(t=>{
  var i=t[0],k=t[1],r=H(i)
  console.log(i+'\n' + (k!=r?'Error '+r+' expected '+k:'Ok '+r)+'\n')
})
<pre id=O></pre>


3

Python 2.7, 153 168 caractères

J'ai aimé ce challenge! Si une liste Python est acceptée en entrée (voir la suite de tests pour des exemples), cette solution fonctionne.

Edit 2016-01-05: ajout d'une ligne (10 caractères) pour fractionner la chaîne en plusieurs lignes.

Brève explication:

  • t est la ligne dans laquelle se trouve la salle (comptée à partir de la ligne supérieure comme tableau index = 0);
  • i est l'index de la pièce dans sa rangée;
  • le bâtiment est calculé comme le nombre de doubles espaces blancs dans la rangée du bas jusqu'à ce que i;
  • floor est le nombre de lignes moins t;
  • room est l'index du premier double espace blanc dans la chaîne inversée depuis ile début de l'étage avec la pièce, ajouté par un espace blanc pour couvrir le cas où la pièce se trouve dans le premier bâtiment.

Code:

def r(l):
 l=h.split(",")
 a,w,s="*","  ",str
 t=l.index(filter(lambda c:a in c,l)[0])
 i=l[t].find(a)
 return s(l[-1][:i].count(w)+1)+s(len(l)-t)+s((l[t][i::-1]+w).find(w))

Suite de tests:

cases = [
         (["*"], 111),
         (["#  #  *  #  #"], 311),
         (["#####","#####","####*","#####","#####"], 135),
         (["         #####","         #####           ######","         #####           ######","#  #  #  #####  #  #  #  ######  *"], 911),
         (["#","#  #","#  #  ##","#  #  ##  ###","#  #  ##  ###  #####","#  #  ##  ###  ##*##  ########","#  #  ##  ###  #####  ########"], 523),
         (["           #","           *","           #","           #","           #","           #","           #","           #","#########  #  #"], 281),
         (["                        ########*","                        #########","                        #########","                        #########","                        #########","                        #########","                        #########","                        #########","#  #  #  #  #  #  #  #  #########"], 999)
        ]

for idx,(hotel,roomnr) in enumerate(cases):
    output=r(hotel)
    if str(output)==str(roomnr):
        result="SUCCESS"
    else:
        result="FAILURE!!!"
    print "Case {} gives output: {}. Correct output is: {}. Result: {}".format(idx,output,roomnr,result)


2

C, 142 138 137 octets

#include <stdio.h>
f,b,x,p=110;main(c){while(~(c=getchar()))c<11?f+=c,b=x=0:x++<p?++b,c&2?c&8?f=p,p=x:0:(b+=50-b%50):0;printf("%d",b+f);}

( 123 119 118 octets + 19 pour la #includeligne)

J'ai volé l'idée de fusion de valeur d'ecatmur, mais je les ai fusionnées de manière tout à fait différente ( sauvegarde de 8 octets à la fin ). Cela fait également la même hypothèse que EOF == -1.

L'entrée est extraite de stdin et ne doit pas contenir d'espaces ni de nouvelles lignes après le dernier bâtiment de la dernière ligne. Un exemple d'entrée serait:

printf "##\n##       #\n##  ##*  #\n##  ###  #" | ./hotel
# or for better visualisation:
printf "##\n##       #\n##  ##*  #\n##  ###  #" | tee /dev/fd/2 | ./hotel;echo ""

Panne:

// Globals initialise to 0
f,     // floor number * 10 + shift
b,     // building number * 100 + room number
x,     // current column
p=110; // will store column of * (must start >= 11*9-2, and 110 will be used later)
main(c){
    while(~(c=getchar()))              // For each character until EOF
        c<11                           //  Is \n? (10)
            ?f+=c,                     //   Add 10 to floor number
             b=x=0                     //   Reset building, room, column
            :x++<p                     //  Else, is column <= *?
                  ?++b,                //   Add to room number
                   c&2                 //   Is # or *?
                      ?c&8             //   If *:
                          ?f=p,p=x:0   //    Set floor to 110, set p to column
                      :(b+=50-b%50)    //   If ' ': go to next building
                  :0;
    printf("%d",b+f);                  // Result is building+room+floor+shift
}

Excellente idée de réutiliser la constante de colonne initiale et d'utiliser les valeurs de caractère comme constantes.
ecatmur

Vous pouvez être en mesure d'enregistrer un octet en changeant &&(f=p,p=x)à ?f=p,p=x:0- le deuxième opérande d'une condition ternaire a entre parenthèses implicites.
ecatmur

@ecatmur bon point; Merci!
Dave

1

Haskell, 128 à 125 octets

l=length
f h|b<-snd$break(elem '*')$lines h,q<-fst(span(<'*')$b!!0)++"*"=l(last$words$q)+10*l b+l(words$take(l q)$last b)*100

Exemple d'utilisation: f "# # * # #"-> 311.

Comment ça marche:

b<-snd$break(elem '*')$lines h      -- split the input into a list of lines
                                    -- and assign b to the lines starting with
                                    -- the one that includes * up to the end,
                                    -- i.e. drop leading lines without the *
q<-fst(span(<'*')$b!!0)++"*"        -- assign q to the line with the *, but strip
                                    -- off all chars after the *

l(last$words$q)                     -- the room on floor number is the length of
                                    -- the last word of q
10*l b                              -- the floor number is 10 times the length of b
l(words$take(l q)$last b)*100       -- the hotel number is 100 times the number of
                                    -- words in the last line cut down to the
                                    -- length of q

                                    -- add for final room number

1

Lua, 165 octets

l={}i=1while(l[i-1]~="")do l[i]=io.read()o=l[i]:find"%*"x=o or x y=o and i or y i=i+1 end print(#l[i-2]:sub(1,x):gsub("%S+%s*","#")*100+(i-y-1)*10+#l[y]:match"#-%*")

Ungolfed

l={}
i=1
while(l[i-1]~="")do
    l[i]=io.read()
    o=l[i]:find"%*" --find "*", and record:
    x=o or x        --position and
    y=o and i or y  --current floor
    i=i+1
end
print(#l[i-2]:sub(1,x):gsub("%S+%s*","#")*100 --[[Take last string of list, and then
                                                  take the substring up until the 
                                                  asterisk. Substitute any substrings
                                                  that include nonspace characters 
                                                  (%S+) followed by a minimum of 0 space 
                                                  characters (%s*) with one character
                                                  (in this code snippet I chose # for no 
                                                  particular reason.) Then take the length 
                                                  of this string, with the # operator. 
                                                  The %S+%s* regex and gsub do the bulk 
                                                  of the magic.
                                                ]]
      +(i-y-1)*10                             --[[Total number of lines minus '*' floor 
                                                  minus one.
                                                ]]
      +#l[y]:match"#-%*")                     --[[Find the substring on the asterisk floor
                                                  with '#' symbols preceding an asterisk.
                                                ]]

0

CoffeeScript, 110 octets & JavaScript, 121 octets

(s)->s.split('\n').reverse().map((f,g)->f.split('  ').map((h,i)->r=h.indexOf('*');s=''+i+g+r if r>-1));111+1*s

Lisible

(s)->
    s.split '\n' 
        .reverse()
        .map (f,fi)->
            f.split('  ')
                .map (h,hi)->
                    ri = h.indexOf('*')
                    s = ''+hi+fi+ri if ri>-1
    111+1*s

Fondamentalement la même chose en Javascript:

(s)=>{s.split('\n').reverse().map((f,g)=>f.split('  ').map((h,i)=>{r=h.indexOf('*');r>-1?s=''+i+g+r:''}));return 111+1*s}

0

Java, 231 octets

String a(String a){String[]b=a.split("\n");int i=0,c=b.length,m;String x,k=" ";for(;i<c;i++){x=b[c-1].substring(0,b[i].indexOf("*")+1);m=x.length();a=m>0?""+(m-x.replace(k+k,k).length()+1)+(c-i)+(m-x.lastIndexOf(k)-1):a;}return a;}

Détartré

 String a(String a) {
     String[] b = a.split("\n");                                // Split the input into floor lines
     int i = 0, c = b.length, m;                                // i=floor line counter c= number of floor lines
     String x, k = " ";
     for (; i < c; i++) {                                       // Loop through floor lines
        x = b[c - 1].substring(0, b[i].indexOf("*") + 1);       // x = part of bottom floor line up to '*' position in current line (Empty string when no '*')
        m = x.length();                                         // m = length of floor line part
        a = m > 0 ? "" + (m - x.replace(k + k, k).length() + 1) // if m>0 ('*' is on this line) set a=building no+floor no+room no.   building no calculated by replacing double space in x with single space and compare length to x (+1) 
              + (c - i)                                         // floor number is total floor lines (c) - floor line loop counter (i)
              + (m - x.lastIndexOf(k) - 1) : a;                 // room number is m ('*' position in x) - position of last space in x (-1)
     }
     return a;                                                  // return the result at the end.
  }

0

Powershell, 154 octets

param($s)filter s{$s|sls $_ -a|% M*|% Le*}(($s-split'
')[-1]|% s*g 0('(?m)^.*\*'|s)|sls '^|  '-a|% M*).Count,('(?ms)(?<=\*.*)$'|s).Count,('#*\*'|s)-join''

Script de test moins joué:

$f = {

param($s)

filter s{
    $s|sls $_ -AllMatches|% Matches|% Length
}                                   # select an array of lengths of all matches of the string $s by pattern $_

$hpos='(?m)^.*\*'|s                 # horizontal position of the room in the source string
$basement=($s-split"`n")[-1]        # basement floor string

$building=($basement|% substring 0 $hpos|sls '^|  ' -AllMatches|% Matches).Count
                                    # truncate the basement to the position of the room
                                    # and count all double spaces or a 'start of string'
$floor=('(?ms)(?<=\*.*)$'|s).Count  # count all 'end of line' after the room
$room='#*\*'|s                      # count all #, preceding the room, and room itself

$building,$floor,$room-join''


}

@(

,(@"
*
"@, 111)

,(@"
#  #  *  #  #
"@,311)

,(@"
#####
#####
####*
#####
#####
"@, 135)

,(@"
        #####
        #####           ######
        #####           ######
#  #  #  #####  #  #  #  ######  *
"@, 911)

,(@"
#
#  #
#  #  ##
#  #  ##  ###
#  #  ##  ###  #####
#  #  ##  ###  ##*##  ########
#  #  ##  ###  #####  ########
"@, 523)

,(@"
        #
        *
        #
        #
        #
        #
        #
        #
#########  #  #
"@, 281)

,(@"
                        ########*
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
                        #########
#  #  #  #  #  #  #  #  #########
"@, 999)

) | % {
    $n,$expected = $_
    $result = &$f $n
    "$($result-eq$expected): $result"
}

Sortie:

True: 111
True: 311
True: 135
True: 911
True: 523
True: 281
True: 999

0

05AB1E , 34 octets

|€SζJðмõ¡εεR'*k>]DOZ©k>;ò®«sĀ€ƶ˜à«

Zip avec des listes de chaînes est actuellement buggé. €SζJaurait pu être juste ζdans l'ancienne version héritée de Python de 05AB1E, mais pour une raison quelconque ne fonctionne plus dans la version de réécriture Elixir.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

|                    # Take the input split by newlines
                     #  i.e. "   ###\n#  ###\n#  ###  ##\n#  ##*  ##"
                     #   → ["   ###","#  ###","#  ###  ##","#  ##*  ##"]
 S                  # Convert each to a list of characters
   ζ                 # Zip, swapping rows and column
    J                # Join them together to a string again
                     #  → [" ###","    ","    ","####","####","###*","    ","    ","  ##","  ##"]
     ðм              # Remove all spaces
                     #  → ["###","","","####","####","###*","","","##","##"]
       õ¡            # Split on empty strings
                     #  → [["###"],[],["####","####","###*"],[],["##","##"]]
ε                    # Map each building to:
 ε                   #  Map each column of the building to:
  R                  #   Reverse the column
   '*k              '#   Get the 0-indexed index of "*"
      >              #   Increase it by 1 to make it 1-indexed
]                    # Close both maps
                     #  → [[0],[],[0,0,1],[],[0,0]]
 D                   # Duplicate the resulting list
  O                  # Sum each building
                     #  → [0,0,1,0,0]
   Z                 # Get the max (without popping)
                     #  → 1
    ©                # Store this max in the register (without popping)
     k>              # Get the index (+ 1) of this max in the sum-list
                     #  → 3
       ;             # Halve it
                     #  → 1.5
        ò            # Round it up to the nearest integer (bankers rounding)
                     #  → 2
         ®           # Retrieve the value from the register again
          «          # Merge the two digits together
                     #  → 21
           s         # Swap so the duplicate list is at the top again
            Ā        # Trutify (0 remains 0, every other integer becomes 1)
                     #  → [[0],[],[0,0,1],[],[0,0]]
                    # For each building:
              ƶ      #  Multiply the integer with the 1-indexed index
                     #  → [[0],[],[0,0,3],[],[0,0]]
               ˜     # Flatten the list
                     #  → [0,0,0,3,0,0]
                à    # Pop the list, and get the max
                     #  → 3
                 «   # Merge it with the other two digits (and output implicitly)
                     #  → 213

0

Dart , 165 octets

F(List s)=>s.indexWhere((a)=>a.contains('*'));f(String s){var b=s.split('\n'),v=F(b),c=b[v].split('  '),w=F(c),x=c[w].indexOf('*')+1;return '${w+1}${b.length-v}$x';}

Essayez-le en ligne!

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.