Inverting รายการของรายการดัชนี


14

แรงบันดาลใจจากนี้โพสต์ StackOverflow

บทนำ

งานของ Bob คือการสร้างสเปรดชีตและจัดระเบียบมัน วิธีที่เขาจัดระเบียบมันมีน้อยมากยกเว้นบ็อบ แต่เขาสร้างรายการสเปรดชีตแต่ละอันที่อยู่ในกลุ่มเดียวกัน มีข้อมูลมากมายในสเปรดชีตที่เขาสร้าง แต่มีข้อมูลเพียงชิ้นเดียวที่เรากำลังดูอยู่ตอนนี้: จำนวนวันระหว่างวันที่เขาเริ่มงานนี้และวันที่เขาสร้างสเปรดชีต ในวันแรกที่เขาสร้างสเปรดชีตสองรายการเขาได้บันทึกพวกเขาทั้งสองเป็น0และจัดเรียงไว้ในตำแหน่งที่เหมาะสม

ตอนนี้หัวหน้าของเขากำลังขอให้ตรวจสอบว่าสเปรดชีตชนิดใดที่เกิดขึ้นในแต่ละวันและเป็นหน้าที่ของคุณที่จะเขียนโค้ดที่จะช่วยบอกบ๊อบ; เขามีสเปรดชีตมากเกินไปที่จะทำด้วยมือ

อินพุต

ข้อมูลของบ๊อบว่าเขาจะช่วยให้คุณมาในรูปแบบของ (0 หรือ 1 จัดทำดัชนี) x = a[i][j]อาร์เรย์หยักที่แต่ละตัวเลขจะอยู่ในรูป aคือสิ่งที่ฉันเรียกอาร์เรย์แบบขรุขระนั้นiเป็นชนิดของสเปรดชีตและxเป็นวันที่ที่อาร์เรย์ถูกสร้างขึ้น jไม่สำคัญ

งาน

เมื่อกำหนดวันสร้างสเปรดชีตที่มีการจัดเรียงตามประเภทแบบขรุขระให้ส่งคืนอาร์เรย์ประเภทสเปรดชีตที่จัดเรียงตามแนวขรุขระด้วยวันสร้างสเปรดชีต

ตัวอย่าง

บ๊อบจะไม่ทิ้งคุณไว้กับข้อมูลนามธรรมนี้ เขามอบสเปรดชีตของเขาบางส่วนให้ฉันเพื่อช่วยคุณในการหาว่าทุกสิ่งควรเป็นอะไร

ตัวอย่างอินพุต (ดัชนี 0):

a = [
[3,2,5,0], # Bob doesn't necessarily sort his lists
[1,3],
[2,1,0,4],
[4,5,3],
[6,6]
]

ตัวอย่างผลลัพธ์ (พร้อมคำอธิบายซึ่งไม่จำเป็นต้องมีของหลักสูตร):

output = [
[0,2] # On day 0, Bob made one type 0 and one type 2 spreadsheet
[1,2] # On day 1, Bob made one type 1 and one type 2 spreadsheet
[0,2] # On day 2, Bob made one type 0 and one type 2 spreadsheet
[0,1,3] # On day 3, Bob made one type 0, one type 1, and one type 3 spreadsheet
[2,3] # On day 4, Bob made one type 2 and one type 3 spreadsheet
[0,3] # On day 5, Bob made one type 0 and one type 3 spreadsheet   
[4,4] # On day 6, Bob made two type 4 spreadsheets
]

โปรดทราบว่าบ็อบไม่ได้ทำสเปรดชีตสองครั้งทุกวันดังนั้นผลลัพธ์อาจจะขรุขระด้วยเช่นกัน แต่เขาจะทำสเปรดชีตอย่างน้อยหนึ่งครั้งทุกวันดังนั้นผลลัพธ์จะไม่จำเป็นต้องมีอาร์เรย์ที่ว่างเปล่า - แม้ว่าคุณจะมีอาร์เรย์ที่ว่างเปล่าในตอนท้าย แต่คุณก็ไม่จำเป็นต้องลบมันออก

กรณีทดสอบเพิ่มเติม:

[[3,5,6,2],[0,0,0],[1,0,3,4]] -> [[1,1,1,2],[2],[0],[0,2],[2],[0],[0]]
[[-1]] -> Undefined behavior, as all input numbers will be non-negative integers. 
[[0],[0],[],[0]] -> [[0,1,3]]

ไม่จำเป็นต้องเรียงรายการภายในของเอาท์พุท

เช่นเคยไม่มีช่องโหว่มาตรฐานและแน่นอนว่าโค้ดที่สั้นที่สุดชนะ

(เนื่องจากนี่เป็นคำถามแรกของฉันโปรดแจ้งให้ฉันทราบถึงสิ่งที่ฉันสามารถทำได้เพื่อปรับปรุงให้ดีขึ้น)


บ๊อบอาจไม่ทำสเปรดชีตบางประเภทหรือ?
xnor

1
@xnor ไม่ Bob จะสร้างสเปรดชีตทุกวัน สเปรดชีตเหล่านี้มีความสำคัญอย่างยิ่งต่อการดำเนินงานของ บริษัท ซึ่งหากบ็อบต้องโทรมาป่วยคนอื่นจะโพสต์ชั่วคราวเพื่อสร้างสเปรดชีตของวันนั้นและบ็อบจัดระเบียบพวกเขาในเช้าวันรุ่งขึ้นก่อนที่จะสร้างสเปรดชีตของเขาเอง
สตีเฟนเอช.

1
@Dennis ฉันรู้สึกเหนื่อยเล็กน้อยเมื่อนำตัวอย่างนั้นมารวมกันและฉันคิดว่ามันแสดงให้เห็น : P แก้ไขแล้ว (ทั้งคู่)!
สตีเวนเอช.

6
ดูดี. นี่เป็นความท้าทายที่ดีมากโดยเฉพาะอย่างยิ่งการพิจารณาว่านี่เป็นครั้งแรกของคุณ :) Btw ในกรณีที่คุณไม่ทราบเรามีกล่องทรายที่ชุมชนสามารถให้ข้อเสนอแนะก่อนที่จะ "อยู่"
Dennis

1
ฉันแก้ไขในคำแถลงตามความคิดเห็นของคุณ " ไม่บ๊อบจะสร้างสเปรดชีตทุกวัน " แต่ตอนนี้ฉันได้ลองปรับคำตอบของตัวเองให้ดีที่สุดแล้วฉันก็ตระหนักว่ามันอาจจะเข้มงวดกว่าที่คุณตั้งใจไว้ อนุญาตอาร์เรย์ว่างเปล่าต่อท้ายหรือไม่ เช่นสามารถ[[0 0]]ให้การส่งออก[[0 0] []]?
Peter Taylor

คำตอบ:





4

Brachylogขนาด 28 ไบต์

:1f.
cdo:Im:?:2f.
t:.m:Im~h?

คำอธิบาย

  • เพรดิเคตหลัก, อินพุต ( ?) = รายการของรายการ

    :1f.              Find all valid outputs of predicate 1 with ? as input
    
  • คำกริยาที่ 1:

    c                 Concatenate the list of lists into a single list
     do               Remove duplicates and sort
       :Im            Take the Ith element of that sorted list
          :?:2f.      Find all valid outputs of predicate 2 with [Element:?] as input
    
  • คำกริยาที่ 2:

    t:.m              Take the (Output)th element of the list of lists
        :Im           Take the Ith element of that list
           ~h?        This element is the element of the input [Element:List of lists]
    



3

CJam ( 30 29 ไบต์)

Mq~{W):W;{:X)Me]_X=W+X\t}/}/`

การสาธิตออนไลน์

อยากรู้อยากเห็นมันสั้นกว่าที่จะแฮ็กไปไหนมาไหนWมากกว่าที่จะใช้eeเป็นหลักเพราะฉันต้องการให้ดัชนีจบลงด้วยตัวแปรอยู่ดี e]บันทึกสองไบต์ในการค้นหาองค์ประกอบสูงสุดก่อนmและเริ่มต้นอาร์เรย์ของm+1อาร์เรย์ว่าง

ขอบคุณMartinสำหรับการประหยัดหนึ่งไบต์ด้วยการจัดเก็บค่าXแทนการเล่นกลรอบกอง

NB ถ้าอนุญาตให้ใช้อาเรย์ว่างเปล่าต่อท้ายจะมีวิธีการ 29- ทางเลือกอื่นแทนการเริ่มต้นอาเรย์ของวันว่างเปล่าจำนวนมากเนื่องจากมีสเปรดชีต:

q~_e_,Ma*\{W):W;{_2$=W+t}/}/`

3

CJam, 20 ไบต์

ขอบคุณ Peter Taylor ที่ให้ฉันใช้รหัสนี้กับโซลูชันของเขาและประหยัด 3 ไบต์

{ee::f{S*\+S/}:~:.+}

บล็อกที่ไม่มีชื่อซึ่งคาดว่าอินพุตจะอยู่ด้านบนสุดของสแต็กและแทนที่ด้วยเอาต์พุต

ทดสอบที่นี่

คำอธิบาย

ee    e# Enumerate the input. E.g. if the input is 
      e#   [[3 5 6 2] [0 0 0] [1 0 3 4]]
      e# this gives:
      e#   [[0 [3 5 6 2]] [1 [0 0 0]] [2 [1 0 3 4]]]
::f{  e# The exact details of how this works are a bit tricky, but in effect
      e# this calls the subsequent block once for every spreadsheet and
      e# its correspond index, so the first time we'll have 0 and 3 on the
      e# stack, the next time 0 5, and at the last iteration 2 and 4.
      e# Note that this is a map operation, so we'll end up with an array
      e# on the stack.
  S*  e#   So the stack holds [... index date] now. We start by creating
      e#   a string of 'date' spaces, so "   " on the first iteration.
  \+  e#   We swap this with the index and append the index.
  S/  e#   Now we split this thing on spaces, which gives us 'date' empty
      e#   lists and a list containing the index, e.g. [[] [] [] [0]].
}
:~    e# This flattens the first level of the result, so that we get a list
      e# of all those lists we just created. This is simply one list for
      e# every spreadsheet with its type in the last element.
:.+   e# Finally we fold pairwise concatenation over this list. All the 
      e# empty lists won't affect the result so we'll just end up with all
      e# the types in lists for the correct date.


2

Mathematica, 35 ไบต์

Table[#&@@@#~Position~i,{i,Max@#}]&

ฟังก์ชั่นที่ไม่มีชื่อซึ่งรับและส่งคืนรายการที่ขาด ใช้ดัชนี 1 ฐาน

โชคดีที่Maxปรับอินพุตทั้งหมดให้แบนโดยอัตโนมัติดังนั้นสิ่งนี้ทำให้เราได้ดัชนีวันสุดท้ายแม้ว่าอินพุตจะเป็นรายการที่ขาด จากนั้นเราก็คำนวณรายการดัชนีตลอดทั้งวัน#&@@@#~Position~i iนิพจน์นี้ค้นหาตำแหน่งiภายในรายการที่ขาด (กลับเป็นอาร์เรย์ของดัชนีที่ระดับความลึกต่อเนื่อง) ดังนั้นค่าที่เราต้องการคือค่าแรกของแต่ละรายการ #&@@@เป็นเคล็ดลับการเล่นกอล์ฟมาตรฐานในการดึงองค์ประกอบแรกจากทุกรายการย่อยโดยใช้#&กับรายการย่อยแต่ละรายการซึ่งเป็นฟังก์ชันที่ไม่มีชื่อที่ส่งกลับอาร์กิวเมนต์แรก

อีกทางเลือกหนึ่งเราสามารถกำหนดโอเปอเรเตอร์ unary สำหรับจำนวนไบต์เดียวกัน (สมมติว่าซอร์สไฟล์ที่เข้ารหัส ISO 8859-1):

±n_:=#&@@@n~Position~#&~Array~Max@n

2

Java, 314 ไบต์

int[][]f(int[][]n){int w=0;Map<Integer,List<Integer>>m=new TreeMap<>();for(int i=0;i<n.length;i++)for(Integer x:n[i]){if(m.get(x)==null)m.put(x,new ArrayList<>());m.get(x).add(i);w=x>w?x:w;}int[][]z=new int[w+1][];for(int i=0,j;i<w+1;i++){z[i]=new int[m.get(i).size()];j=0;for(int x:m.get(i))z[i][j++]=x;}return z;

รายละเอียด

public static Integer[][] f(Integer[][]n)
{
    int w=0;
    Map<Integer,List<Integer>>m=new TreeMap<>();

    for(int i=0;i<n.length;i++)
    {
        for(Integer x : n[i])
        {
            if(m.get(x)==null) m.put(x,new ArrayList<Integer>());
            m.get(x).add(i);
            w=x>w?x:w;
        }
    }

    Integer[][]z=new Integer[w+1][];
    for(int i=0,j; i<w+1; i++)
    {
        z[i]=new Integer[m.get(i).size()];
        j=0;for(Integer x : m.get(i))z[i][j++]=x;
    }

    return z;
}

1
คุณต้องการจริงๆMapเหรอ?
Leun Nun

0

Perl 5, 48 ไบต์

รูทีนย่อย:

{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}

เห็นมันในการดำเนินการเช่นนี้:

perl -e'print "@$_$/" for sub{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}->([3,2,5,0],[1,3],[2,1,0,4],[4,5,3],[6,6])'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.