11
\$\begingroup\$

I just got a job as a postman and I need your help to keep it. I have to order a lot of mails before I go out to deliver them.

Streets are numbered strictly sequentially, starting with 1 at the start of the street, and continuing in order skipping no numbers until the end, with odd numbers on the left side and evens on the right side. Plus houses were added later so we may also have letters appended to the civic number.

The chest contains all mail of the city so I have to choose only mails of my street.

I need your help to order the mails faster. What I ask you is to write a function or full program taking:
- A street name.
- A list of civic numbers ordered following my path.
- A list of addresses (representing the mail chest).

And output a list of addresses containing only the ones of my street, ordered following the list of civic numbers.

An address has the form :

 Person Name/n   
 CivicN Street Name

Where CivicN is a number that can be followed by a '/' and an UPPERCASE LETTER (10 10/B). If you prefer, lowercase is acceptable.

If Streets Names overlaps they are considered different streets:

Church Road  != Saint Lorenz Church Road 

We omit the rest of the address for simplicity (assuming it is the same for every mail)

Letters must be delivered fast so shortest answer wins.

EXAMPLE:

Layout :

 1 1/B     3 5 7      9 11 13     
 ==============================    
       2 4       4/B 6           

Input :

"Tea Avenue"
["1","1/B","2","4","3","5","7","4/B","6","9","11","13"]
["Mrs. Pie O. Pinky\n6 Tea Avenue","Ms. Kita I. Omeeha\n6 Tea Avenue","Mr. Raile A. Lee\n26 Uea Grove","Odd O. Nic\n76 Mira Road","Mrs. Fuel Tee\n78 Uea Grove","Ny O. Ondip\n55 Uea Grove","Mrs. Black\n67 Uea Grove","Ollie E.\n11 Tea Avenue","Mr. Urna Li\n75 Mira Road","Ms. Polly\n2 Tea Avenue"]

Output :

Ms. Polly
2 Tea Avenue  

Mrs. Pie O. Pinky 
6 Tea Avenue 

Ms. Kita I. Omeeha
6 Tea Avenue 

Ollie E.
11 Tea Avenue

Input :

"Church Road"
["1","3","5","5/B","2","4","7","7/B","6","9","9/B","11","11/B"]
["Billy Ray V.\n5 Church Roadside East","Ms. Mia\n5 Church Road","Mrs. Dadeos\n9/B Church Road","Dr. Ymin U.\n3 Church Road","Atty. Nerou\n3 Church Road","Ollie A. Chaim\n6 Saint Lorenz Church Road","Ms. Rose\n5 Church Road","Alf Taohy\n79 Berry Road","Ms. Ootr E.\n5 Saint Lorenz Church Road","Lol E.\n21 Berry Road","Ms. Norton\n2 Church Road"]

Output :

Dr. Ymin U.
3 Church Road

Atty. Nerou
3 Church Road

Ms. Mia
5 Church Road

Ms. Rose
5 Church Road

Ms. Norton 
2 Church Road" 

Mrs. Dadeos
9/B Church Road

Test generator: Try it online! Change string_wrapper_left/right and separator to modify formatting.

Rules :
- Standard loopholes are forbidden.
- Standard input/output methods.
- Shortest answer in bytes wins.

\$\endgroup\$
  • 5
    \$\begingroup\$ I was afraid you were going to ask us to solve the travelling salesman problem. \$\endgroup\$ – Jitse Oct 1 '19 at 11:59
  • 3
    \$\begingroup\$ @AZTECCO Thanks! It is highly recommended to have several test cases embedded in your post, not just in the demo code. \$\endgroup\$ – Jitse Oct 1 '19 at 12:46
  • 2
    \$\begingroup\$ Don't you mean "yes they can overlap, they are different streets" or "no they cannot overlap, you won't get test cases like this"? Your sentence contradicts itself right now. ;) But I don't mind if you specify it in the challenge. If you do mean that test cases like that are possible, I'll edit my 05AB1E answer to account for it. And @Jitse would have to change his Python answer as well in that case. \$\endgroup\$ – Kevin Cruijssen Oct 1 '19 at 13:49
  • 2
    \$\begingroup\$ Oh.. I meant "yes they can overlap, they are considered different streets" \$\endgroup\$ – AZTECCO Oct 1 '19 at 14:49
  • 2
    \$\begingroup\$ Can confirm. I used to work as a Saturday postman as well many years ago. :) Although in almost all streets of my delivery districts it was more time efficient to just park my bike at the edge of the street, walk one way and deliver all odd numbers, and then walk the other side back doing all even numbers, ending up at my bike again. Then again, with big streets, busy periods like Christmas, or loads of commercial folders, I usually had to walk back to my bike in between a few times because I couldn't carry all post of the entire street in one go.. >.> \$\endgroup\$ – Kevin Cruijssen Oct 1 '19 at 21:17
4
\$\begingroup\$

Jelly, 13 bytes

,⁵KỴṪ⁼ɗƇ@ɗ€ẎY

A full program accepting three arguments - a list of civic numbers on your named street, a list of the addresses in the mail chest, and your street name - which prints the addresses to which you need to deliver in the order of the given civic numbers.

Try it online!

How?

,⁵KỴṪ⁼ɗƇ@ɗ€ẎY - Main link: civic numbers, addresses
          €   - for each (civic number):
         ɗ    -   last three links as a dyad - i.e. f(civic number, addresses):
,⁵            -     pair (the civic number) with 3rd program input (the street name)
  K           -     join (that) with a space -- i.e. X=civic number+' '+street name
        @     -     with swapped arguments i.e. f(addresses, X):
       Ƈ      -       filter (the addresses) keeping those for which:
      ɗ       -         last three links as a dyad - i.e. f(address, X):
   Ỵ          -           split (address) at newlines
    Ṫ         -           tail (get the second line)
     ⁼        -           equals (X)?
           Ẏ  - tighten (the list of lists to a single list)
            Y - join with newlines
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 15 13 12 bytes

ε²ðýUʒ¶¡Xk]˜

-2 bytes by porting @JonathanAllan's Jelly answer, so make sure to upvote him!
-1 byte thanks to @Grimy.

Inputs are in the order: [list of civic numbers], street name, [list of addresses].

Try it online.

Explanation:

ε       # Map over the (implicit) input-list of civic numbers
 ²      #  Push the second street-input
  ðý    #  And join the two values by a space
    U   #  Pop and store this street + num string in variable `X`
 ʒ      #  Filter the (implicit) input-list of addresses by:
  ¶¡    #   Split on newlines
    Xk  #   Get the index of string `X` (street + num) in this list,
        #   which will be either -1 (not found), 0 (first address-line), or 
        #   1 (second address-line), and only 1 is truthy in 05AB1E
]       # After both the inner filter and outer map:
 ˜      # Flatten the array to remove any empty inner lists
        # (after which the result is output implicitly)
\$\endgroup\$
  • \$\begingroup\$ Waiting for edit, thanks a lot for the help ! \$\endgroup\$ – AZTECCO Oct 1 '19 at 15:54
  • \$\begingroup\$ I've edited a test case with overlap test case adding "Billy Ray V.\n5 Church Roadside East" , he should not appear in the output, please fix your answer. Sorry for the inconvenience, I'll pay more attention on my challenges in the future. \$\endgroup\$ – AZTECCO Oct 3 '19 at 16:26
  • \$\begingroup\$ @AZTECCO Should be fixed now by using Grimy's first golfing suggestion. \$\endgroup\$ – Kevin Cruijssen Oct 3 '19 at 16:58
  • \$\begingroup\$ Thanks for your time! \$\endgroup\$ – AZTECCO Oct 3 '19 at 19:02
2
\$\begingroup\$

JavaScript (Node.js), 58 bytes

(s,n,a)=>n.flatMap(n=>a.filter(x=>x.split`
`[1]==n+' '+s))

Try it online!

Commented

(s, n, a) =>          // s = street name, n[] = civic numbers, a[] = addresses
  n.flatMap(n =>      // for each civic number n in n[]:
    a.filter(x =>     //   for each address x in a[]:
      x.split`\n`[1]  //     keep it if the 2nd part is equal to
      == n + ' ' + s  //     n + space + expected street name
    )                 //   end of filter()
  )                   // end of flatMap() (empty entries are discarded)
\$\endgroup\$
  • \$\begingroup\$ First answer! You saved my job! Thanks for improvement btw \$\endgroup\$ – AZTECCO Oct 1 '19 at 15:50
2
\$\begingroup\$

Ruby, 65 bytes

->s,o,n{n.grep(/\d\S* #{s}$/).sort_by{|i|o.index i[/\d+(\/.)?/]}}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Perl 5, 51 bytes

sub{my($r,$a,@B)=@_;map{$n=$_;grep/
$n $r$/,@B}@$a}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I've edited a test case with overlap test case adding "Billy Ray V.\n5 Church Roadside East" , he should not appear in the output, please fix your answer. Sorry for the inconvenience, I'll pay more attention on my challenges in the future. \$\endgroup\$ – AZTECCO Oct 3 '19 at 16:26
  • \$\begingroup\$ fixed +1byte, adding $ anchor at the end of regex \$\endgroup\$ – Nahuel Fouilleul Oct 3 '19 at 18:56
  • \$\begingroup\$ Thanks for your time \$\endgroup\$ – AZTECCO Oct 3 '19 at 19:03
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 63 bytes

(a,b,c)=>b.SelectMany(x=>c.Where(l=>l.Split('\n')[1]==x+" "+a))

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 3, 79 85 bytes (thanks to squid)

d=lambda s,n,a:n and[k for k in a if k.split('\n')[1]==n[0]+' '+s]+d(s,n[1:],a)

old:

d=lambda s,n,a:[k for k in a if k.split('\n')[1]==n[0]+' '+s]+d(s,n[1:],a)if n else[]
\$\endgroup\$
  • 1
    \$\begingroup\$ 79 bytes unless this breaks it somehow \$\endgroup\$ – Reinstate Monica Oct 2 '19 at 19:23
  • \$\begingroup\$ cool, I didn't know you could use 'and' to produce outputs like that \$\endgroup\$ – Legorhin Oct 2 '19 at 19:34
1
\$\begingroup\$

Python 3, 65 bytes

lambda s,n,m:[a for i in n for a in m if a.endswith('\n%s '%i+s)]

Try it online!

Also works in Python 2.

For each number i in the list of civic numbers n, the function will iterate over all addresses a in the list of mail m and keep the ones where the combination of the civic number i and the street name s matches with a. This results in a sorted and filtered list.

\$\endgroup\$
1
\$\begingroup\$

Kotlin, 145 bytes

fun p(s:String,o:List<String>,m:List<String>):List<String>
=if(o.size<1)List(0){""}
else
m.filter{it.split("\n")[1]==o[0]+" "+s}+p(s,o.drop(1),m)

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.