text:
Meeting splitter
Introduction
Large meetings waste working time. Our aim is to split a large meeting into a number of smaller meetings, so the average number topics that a person discusses is minimized but every person has to be in every meeting they are interested in.
Input
Given is a function from a set of topics \$T\$ to a set of persons \$P\$ that are interested in this topic $$f:T \rightarrow 2^P$$ and maximum partition size \$m\$.
This is encoded as an array of arrays, where element \$f(i)\$ contains the topics of person \$i\$.
Test Case
m = 3
f = [
[9,7],
[3,7,6,4],
[3,1,2],
[7,5,4,2],
[6,2,8,1,4],
[3,7,2,9,8],
[4,3,2],
[3,4,6],
[1,9,5,3],
[6,4,1,2],
[9,7,3,1],
[1,7,4],
[5,1,7,2],
[5,2,7],
[4,2,6,9],
[6,4,1],
[6,5,9,8],
[9,1],
[9,1,5,6],
[1,2,4,8,7]
]

Output
Find a partition of \$T\$ (a split into subsets that are disjoint and that cover the whole set) into $$X = {T_1, T_2, \ldots, T_n}$$ where \$n\le m\$, so that the following term is minimized:
$$r = \sum_{T' \in X}{(|(\bigcup_{t \in T'} f(t))|\times |T'|)} $$
To help understand \$r\$, if each topic takes an hour to discuss, then \$r\$ is the total amount of person hours required for the meetings.
If there are multiple partition sizes with the same \$r\$, \$n\$ should be minimized as well.
The output should contain the partition \$X\$ as a two-dimensional array, such as:
$$X = [[0,1,2,3],[4,5,6],[7,8,9]] $$
Winning Condition
I am looking for the fastest algorithm that finds the absolute minimum \$r\$ and \$n\$.
If that is not possible in polynomial time, then I am also looking for an  polynomial algorithm that has the lowest upper bound on \$r\$ in relation to the absolute minimum \$r\$ (e.g. double).

What would be the winning condition? Challenges here should always have a win condition. code-challenge is a valid win condition tag, but in that case you should state what the win condition is for the challenge. If I understand it correctly you are looking for a fastest-algorithm win condition instead?

@KevinCruijssen Sorry, I should have stated that more clearly, I will edit the answer. The problem is that I don't know the complexity class of the problem and depending on it, it is either one of those. I will add the other tag and hope that is OK.

Since you tagged it [tag:fastest-algorithm] and you don't know the complexity, you might want to remove that restriction (a competing answer will strive for a polynomial algorithm).

@BMO: The idea was that in that case a polynomial approximation is to be found but I agree that a non-polynomial non-approximate fastest algorithm would be interesting as well so I removed the tag and edited the objective.

@KonradHöffner Are we allowed to assume that the input list of interesting topics is sorted l to g? (aka treat it as a set in code as well as equation)

I feel like your r function is not effective. It seems to me that splitting all the topics would give the minimum value for r.

@moonheart08: Sure! You can assume it is sorted.

I'd like a description of the term r in words. You don't really describe what it is or means.

@kroppeb: Indeed that would yield the minimum value of r if the maximal allowed partition size m is equal or higher than the number of topics. However we cannot assume that in the general case.

@mbomb007: r is the sum of topics that all persons must discuss. If each topic takes an hour to discuss, then it is the total amount of person hours required for the meetings.

@Konrad - that description ("total amount of person hours") is really helpful - you should add that into the question.

How is the solution not a variant of MIN_CUT in the similarity between topics as measured by participants overlap?

@NofP: I didn't know about MIN_CUT, thanks for bringing this up! But I don't quite see how this problem can be transformed to MIN_CUT, could you elaborate in an answer?

R with lpSolve
Turn the problem into an integer linear programming problem with \$2^t\$ variables and \$t+1\$ constraints, where \$t\$ is the number of topics. The cost function is modified by multiplying it with \$m\$ and adding the size of the partition. This makes the size of the partition a secondary optimization goal.
require("lpSolve")

decode <- function(n) {
  res <- c()
  i <- 1
  while (n>0){
    if (n %% 2 == 1)
      res <- c(res,i)
    i <- i+1
    n <- n %/% 2
  }
  res
}

opt <- function(m,p) {
  nr_pers <- length(p)
  nr_topics <- max(unlist(p))
  x <- array(0,c(nr_topics,nr_pers))
  for (i in 1:nr_pers)
    for (j in 1:length(p[[i]]))
      x[p[[i]][[j]],i] <- 1
  l <- array(0,c(2^nr_topics,nr_pers))
  cb <- rep(0,2^nr_topics)
  w <- rep(1,2^nr_topics)
  mt <- matrix(0,nr_topics+1,2^nr_topics)
  mt[nr_topics+1,1] <- 1
  len <- 1
  for (i in 1:nr_topics) {
    for(j in 1:len) {
      j1 <- len+j
      l[j1,] <- l[j,]+x[i,]
      cb[j1] <- cb[j] + 1
      w[j1] <- m*sum(l[j1,] != 0)*cb[j1]+1
      mt[,j1] <- mt[,j]
      mt[nr_topics+1-i,j1] <- 1
    }
    len <- 2*len
  }
  dir <- c(rep("=",nr_topics),"<=")
  rhs <- c(rep(1,nr_topics),m)
  sol <- lp("min",w,mt,dir,rhs,all.bin=TRUE)$solution
  res <- list()
  j <- 1
  for (i in 1:length(sol))
    if (sol[i]==1) {
      res[[j]] <- decode(i-1)
      j <- j+1
    }
  res
}

# test case
f <- list(
       c(9,7),
       c(3,7,6,4),
       c(3,1,2),
       c(7,5,4,2),
       c(6,2,8,1,4),
       c(3,7,2,9,8),
       c(4,3,2),
       c(3,4,6),
       c(1,9,5,3),
       c(6,4,1,2),
       c(9,7,3,1),
       c(1,7,4),
       c(5,1,7,2),
       c(5,2,7),
       c(4,2,6,9),
       c(6,4,1),
       c(6,5,9,8),
       c(9,1),
       c(9,1,5,6),
       c(1,2,4,8,7))

On debian, this needs the package r-cran-lpsolve.
The code assumes that the topics start with 1 and that each topic number up to the maximum is used. Input and output is as list of vectors, which is not too nice. The test case example is defined in the code, but the list can of course also be entered directly.
To use it, start R and then source the code file and use the function like this:
> source("opt.r")
Loading required package: lpSolve
> opt(3,f)
[[1]]
[1] 1 2 3 4

[[2]]
[1] 6 8

[[3]]
[1] 5 7 9

>

So [[1,2,3,4],[6,8],[5,7,9]] is an optimal partition for the test case.

Wow thanks, I didn't think about ILP at all! What is the complexity of that approach? How long did it run? I can only test it later but accepted it already as the bounty is running out.

I think you can and should handle the bounty and acceptance separately. The preparation step is exponential in the number of topics, linear in the number of persons and independent from m. The example test case takes less than a second.


text:
ASCII Calendar Planner
Given a list of activities and their start time/date, output an ASCII-art calendar showing the activities on the appropriate days. All activities are guaranteed to be in the same month, no two activities will be on the same day, and all activities are guaranteed to fit within the calendar box.
The calendar has the date in the upper-left corner of each box, the boxes are 9 spaces wide by 5 spaces tall, surrounded by - and |. The two-letter abbreviation for the day of the week is centered above the first row, and the weeks start with Sunday.
For example, given the following activities:
10/5/2018 - 9:00am - Sandbox calendar challenge
10/9/2018 - 9:00am - Post challenge to main
10/10/2018 - 10:00am - Profit
10/31/2018 - 7:30pm - Halloween party

Output this corresponding calendar:
    Su        Mo        Tu        We        Th        Fr        Sa
-----------------------------------------------------------------------
|         |1        |2        |3        |4        |5        |6        |
|         |         |         |         |         |9:00am   |         |
|         |         |         |         |         |Sandbox  |         |
|         |         |         |         |         |calendar |         |
|         |         |         |         |         |challenge|         |
-----------------------------------------------------------------------
|7        |8        |9        |10       |11       |12       |13       |
|         |         |9:00am   |10:00am  |         |         |         |
|         |         |Post     |Profit   |         |         |         |
|         |         |challenge|         |         |         |         |
|         |         |to main  |         |         |         |         |
-----------------------------------------------------------------------
|14       |15       |16       |17       |18       |19       |20       |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------
|21       |22       |23       |24       |25       |26       |27       |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------
|28       |29       |30       |31       |         |         |         |
|         |         |         |7:30pm   |         |         |         |
|         |         |         |Halloween|         |         |         |
|         |         |         |party    |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------

Clarifications

The schedule words (matching [A-Za-z]+) will delimited by a single space between them (as in the example).
Splitting the text on word boundaries is sufficient. No need for hyphenating words.
If February starts on a Sunday in a non-leap-year, you only will have four calendar rows.
If a 31-day month (e.g., August) starts late in the week, you may have to output six calendar rows.

I/O and Rules

Your code must handle dates at least between 0001-01-01 and 9999-12-31 in the Gregorian calendar, including leap years as appropriate. For example, if given input 2016-02-13 9:00am Test, the output calendar should have February 29.
Input date format can be in any desired format. ISO 8601, a datetime object, a particularly-formatted string, etc. Input parsing is not the interesting part of this challenge.
Input and output can be by any convenient method.
Leading/trailing newlines or other whitespace are optional, provided that the characters line up appropriately.
Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
Output can be to the console, returned as a list of strings, returned as a single string, etc.
Standard loopholes are forbidden.
This is code-golf so all usual golfing rules apply, and the shortest code (in bytes) wins.

1.) Do you have to split the activity names on the word boundaries?
2.) When you have a non-leapyear February starting on a Sunday, do you have only 4 rows?
3.) When you would need 6 rows to show the month (ex. August starting on Saturday) what happens?

Related (easier).

@nedla2004 1) Yes, word boundaries will work fine. 2) That is correct, 4 rows. 3) Your calendar will need to show 6 rows. I'll edit in clarifications.

@Arnauld Yes, that's a fair assumption

1752-09-02 - 09:00am - Wife's Birthday Tomorrow (14th!)

@ngm HAH. That's a wonderful joke thanks for that laugh-- and it already breaks the first submission ;).

Ohhh I didnt see that. I assumed you said the latter hence the joke.

JavaScript (ES8), 380…321 320 bytes
Takes input as (y,m,e) where:

y is the year
m is the month, 0-indexed
e is an object whose keys are the days and whose values are the events in [hour, task] format

(y,m,e)=>`SuMoTuWeThFrSa
`.split(/(..)/).join`    `+(p='-'.repeat(d=71)+`
`)+(g=i=>++d<1|(x=G`getMonth`==m)|i%7?`|${[h,t]=e[d]||E,o=[x*d,h],q=E,t&&t.split` `.map(s=>q=(u=q?q+' '+s:s)[9]?o.push(q)&&s:u),[...o,q][r%5]||E}`.padEnd(10)+(++i%7?E:`|
`+(++r%5?(d-=7,E):p))+g(i):E)(E=r='',d=-(G=s=>new Date(y,m,d)[s]())`getDay`)

Try it online!
How?
Below are some important parts in the code.
Header
The header line is generated with:
'SuMoTuWeThFrSa\n'.split(/(..)/).join`    `

When split() is used with a regular expression containing a capturing group, this group is included in the output array. In this case, it gives:
[ '', 'Su', '', 'Mo', '', 'Tu', '', 'We', '', 'Th', '', 'Fr', '', 'Sa', '\n' ]

We join this array with 4 spaces, leading to:
'    Su        Mo        Tu        We        Th        Fr        Sa    \n'

which is exactly what we want.
Month structure
The helper function \$G\$ builds a date from the input year \$y\$ and input month \$m\$ (which are constant) and the day \$d\$ (which is dynamic). Its parameter is a method name, which allows to extract either the day of the week or the month.
G = s => new Date(y, m, d)[s]()

It is first used to identify the day of the week of the first day of the month, so that we can move back to the last Sunday from there. It is then used to detect when we enter back the correct month and when we leave it (this information is stored in the Boolean \$x\$).
Event formatting
The following code is used to format an event.
[h, t] = e[d] || E,           // split the content of the event into h and t
o = [x * d, h],               // set the first 2 entries of o[]: day and hour
q = E,                        // we start with q = empty string
t &&                          // skip this .map() loop entirely if t is not defined
t.split` `                    // split the string on spaces
.map(s =>                     // for each word s:
  q =                         //   update q:
    (u = q ? q + ' ' + s : s) //     u is the concatenation of the previous string with
                              //     the new word, separated by a space if needed
    [9] ?                     //     if u is more than 9 character long:
      o.push(q)               //       push the previous string in o[]
      && s                    //       and reset q to s
    :                         //     else:
      u                       //       update q to u
),                            // end of map()
[...o, q][r % 5]              // append the last pending part to o[] and extract the
|| E                          // relevant row; or use an empty string by default

Python 2, 326 324 315 312 307 bytes
import calendar as c,textwrap as t
c.setfirstweekday(6)
y,m,e=input()
print' Su Mo Tu We Th Fr Sa\n'.replace(' ',' '*8)[4:]+'-'*71
for w in c.monthcalendar(y,m):
 for l in zip(*[[d or'',a]+(t.wrap(b,9)+['']*3)[:3]for d in w for a,b in[e.get(d,'  ')]]):print'|'+'|'.join('%-9s'%v for v in l)+'|'
 print'-'*71

Try it online!
Same input as Arnauld's JS answer:
Takes input as (y,m,e) where:

y is the year
m is the month, 1-indexed
e is an object whose keys are the days and whose values are the events in (hour, task) format

Charcoal, 215 206 bytes
Ｓθ≔Ｉ⪪§⪪θ ⁰/η≔⁻⁺×¹²⊟η⊟η²η≔ＥＥ²⁻ηι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷η≔±⊟ηζ≔⁺²⁸﹪⁺⊟ηζ⁷ε⭆⪪SuMoTuWeThFrSa²◨◧ι⁶χ↓←⁷¹Ｗ‹ζε«↘Ｆ⁷«Ｐ↓⁵→≦⊕ζＦ⁼Ｉζ§⪪θ/⁰«≔⪪θ - θ≔⟦ω◨§θ¹¦⁹⟧δＦ⪪⊟θ ⊞δ⎇‹⁺Ｌ§δ±¹Ｌμ⁹⁺⁺⊟δ μμＰ⪫δ¶Ｓθ»◨×››ζ⁰›ζεＩζ⁹»↓⁵←⁷¹

Try it online! Link is to verbose version of code. Takes dates in d/m/yyyy format. Explanation:
Ｓθ

Input the first event.
≔Ｉ⪪§⪪θ ⁰/η

Extract the date and split on /s.
≔⁻⁺×¹²⊟η⊟η²η

Convert to months since March, 1 BC. I want to calculate the day of week of the first of both next month and the current month, and working in months is easier than keeping the months and years separate and carrying at the end of the year, plus it also allows me to start counting months beginning at March instead of January, which is required by Zeller's congruence.
≔ＥＥ²⁻ηι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷η

Use a modified Zeller's congruence to extract the day of the week of the first day of next month and this month. The basic part relies on the fact that the number of days from October 30th of the previous year to the 1st of a given month where m = 4 for March and m = 14 for January of the following year is given by the formula m * 153 / 5, however we can subtract 140 because we only care about the day of the week. It then remains to make adjustments due to the year; each year adds a day, each 4th year adds an extra day, each 100th year subtracts a day, and each 400th year adds a day again. (As I'm working in months these values are all multiplied by 12.) Rather conveniently this directly gives me the answer in terms of a Sunday-indexed week (normally you would add the day of month and start counting on Saturday).
≔±⊟ηζ

Negate the day of the week and save it as the current day of the month.
≔⁺²⁸﹪⁺⊟ηζ⁷ε

Calculate the number of days in the month from the day of the week of the two months.
⭆⪪SuMoTuWeThFrSa²◨◧ι⁶χ

Output the day headers.
↓←⁷¹

Print the top row of -s.
Ｗ‹ζε«

Loop until the last day of the month has been output.
↘

Move the cursor to the start of the next row.
Ｆ⁷«

Process 7 days at a time.
Ｐ↓⁵→

Print the column of |s to the left.
≦⊕ζ

Increment the current day of the month.
Ｆ⁼Ｉζ§⪪θ/⁰«

If the current day of the month is the day of the current event, ...
≔⪪θ - θ

... extract the other parts of the event, ...
≔⟦ω◨§θ¹¦⁹⟧δ

... pad the time to 9 spaces and save it and an empty string as a list, ...
Ｆ⪪⊟θ

... split the description on spaces and loop over them, ...
⊞δ⎇‹⁺Ｌ§δ±¹Ｌμ⁹⁺⁺⊟δ μμ

... adding each word to the previous word if it will fit; ...
Ｐ⪫δ¶

... output the time and description (Ｐδ doesn't work, might be a Charcoal bug?), ...
Ｓθ»

... and input the next event.
◨×››ζ⁰›ζεＩζ⁹»

If the current day of the month is between 1 and the last day of the month then output it, otherwise just output enough spaces to move to the next day.
↓⁵←⁷¹

At the end of the week, print the right column of |s and the bottom row of -s.

Maybe I skipped over it in your verbose TIO code, but are you sure your Zeller's congruence implementation is complete? It seems to be correct for the months March through December, but for the months January and February year-1 should be used instead of year and month+12 should be used instead of month. Or did you somehow simplify the algorithm that I mentioned in this 05AB1E answer of mine which is equal to the one from Wikipedia?

@KevinCruijssen This is basically why I calculate the number of months since March, 1BC, but it's too complicated to explain further in a comment.

@KevinCruijssen I've updated my explanation; I hope you find it helpful.

Thanks! That's indeed a nice modified formula, and I now understand the reasoning behind it. Thanks a lot for adding it to the explanation. +1 from me.

Java (JDK), 538 439 428 425 bytes
Quite possibly the longest Code Golf solution I've ever posted. Still trying to golf it down from here but it's a struggle.
Managed to knock off 99 bytes by changing the input format and using some regex parsing, and another 11 from miscellaneous bits.
3 extra bytes off thanks to Kevin!
Taking inspiration from other answers, it takes input as the year, month and a Map of days to a String representing the time and event in the format <time>-<event>.
(y,m,M)->{var C=java.util.Calendar.getInstance();C.set(y,m-1,1);String r=",Su,,Mo,,Tu,,We,,Th,,Fr,,Sa\n".replace(",","    "),e;for(int x=C.getActualMaximum(5),l=0,b=0,j,c,i=0;i<7;r+="\n",l+=b<=x&++i>6?7*(i=1):0)for(j=0;j<71;b=l+j/10+2-C.get(7),e=(e=M.get(b))!=null?e.replaceAll("([^-]{1,9})(-| |$)","$1-")+" - ":null,r+=e=i%6<1?"-":c<1?"|":c*i<2&b>0&b<=x?b+"":c<2&e!=null?e.split("-")[i-2]:" ",j+=e.length())c=j%10;return r;}

Try it online!

Ungolfed
(y,m,M)->{                                              // Lambda taking input as a year, month and map
  var C=java.util.Calendar.getInstance();               // Creates a new Calendar instance
  C.set(y,m-1,1);                                       // Sets the calendar to the first of the month in the given year
  String r=",Su,,Mo,,Tu,,We,,Th,,Fr,,Sa\n"              // Creates the header row by replacing
    .replace(",","    "),e;                             // commas with 4 sets of spaces

  for(                                                  // Creates 7 rows for a calendar row
      int x=C.getActualMaximum(5)                       // Stores last day of the month
      ,l=0,b=0,j,c,i=0;i<7;                             // Initialises other integers
      r+="\n",                                          // Add new line each row
      l+=b<=x&++i>6                                     // If end of a calendar row is reached, and current day is less than max
        ?7*(i=1)                                        // Set i to 1 and add 7 to line count to create another calendar row
        :0)                                             // Otherwise do nothing

    for(j=0;j<71;                                       // Loop 71 times, appending characters to create a row
        b=l+j/10+2-C.get(7),                            // Determine the day of the box we're in
        e=(e=M.get(b))!=null?                           // Get the event for this day from the map and if not null
            e.replaceAll("([^-]{1,9})(-| |$)","$1-")      // Do some regex to separate the line entries by hyphens
            +" - "                                      // Append extra hyphen to prevent array out of bounds
            :null,                                      // Otherwise do nothing
        r+=e=i%6<1?"-":                                 // If it's the first line of a calendar row, append -
           c<1?"|":                                     // If it's the first column of a box, append |
           c*i<2&b>0&b<=x?b+"":                         // If it's the second column of a box, the second row,
                                                        // and less than the max day, append the day
           c<2&e!=null?e.split("-")[i-2]:               // If it's any other row and there is an event then split and append correct line
           " ",                                         // Else just append a space
        j+=e.length())                                  // Increase the row character count by the length to append
          c=j%10;                                       // Set the column of box (this is the only thing in the loop so happens first)

  return r;                                             // return the calendar string!
}

&&(i=1)<2?7:0 can be ?7*(i=1):0 to save 3 bytes.

@KevinCruijssen Nice one thanks!

Suggest b>x|i++<6?0:7*(i=1) instead of b<=x&++i>6?7*(i=1):0 and c*i>1|b<1|b>x?c<2&e!=null?e.split("-")[i-2]:" ":b+"" instead of c*i<2&b>0&b<=x?b+"":c<2&e!=null?e.split("-")[i-2]:" "

Red, 674 651 bytes
func[a][z: func[a b c][to-tuple reduce[a b c]]c: a/1 c/4: 1 d: c + 31
d/4: 1 d: d - 1 e: 1 + c/weekday % 7 if e = 0[e: 7]foreach
t[:Su:Mo:Tu:We:Th:Fr:Sa][prin pad pad/left t 6 10]h:
pad/with"-"71 #"-"print["^/"h]m: copy[]foreach[i b]a[put m z r:(t: e - 1)+
i/4 / 7 + 1 n: i/4 % 7 + t 2 b/1 t: split b/2" "l: 0
until[if t/2[if 10 >((length? t/1)+ length? t/2)[t/1:
rejoin reduce[t/1" "take next t]]]put m z r n 2 + l: l + 1 take t
tail? t]i: 0]n: k: 0 repeat v(g: e - 1 + d/4)/ 7 + sign? g % 7[repeat
r 5[repeat i 7[t: copy"|"if i = e[k: 1]if all[k = 1 r = 1 n < d/4][append t
n: n + 1]if s: select m z v i r[append t s]prin pad t 10]print"|"]print h]]

Try it online!
More readable:
func [ a ] [
    c: d: a/1
    c/4: d/4: 1
    d: d + 31
    d/4: 1
    d: d - 1
    e: 1 + c/weekday % 7
    if e = 0[e: 7]
    g: e - 1 + d/4
    w: g / 7 + sign? g % 7
    foreach t [ :Su :Mo :Tu :We :Th :Fr :Sa ] [
        prin pad pad/left t 6 10
    ]
    h: pad/with "-" 71 #"-"
    print[ "^/" h ]
    m: copy #()
    foreach[ i b ] a [
        n: i/4 % 7 + t: e - 1
        r: t + i/4 / 7 + 1
        put m to-tuple reduce[ r n 2 ] b/1
        t: split b/2" "
        i: 0
        until [
            if t/2 [ if 9 >= ((length? t/1) + (length? t/2)) [
                t/1: rejoin reduce[t/1" "take next t]
                ]
            ]
            put m to-tuple reduce [ r n 2 + i: i + 1 ] take t
            tail? t
        ]

    ]
    n: 0
    g: off
    repeat v w [
        repeat r 5 [
           repeat i 7 [
                t: copy "|"
                if i = e[ g: on ]
                if all [ g r = 1 n < d/4 ] [ append t n: n + 1 ]
                if s: select m to-tuple reduce [ v i r ]
                    [ append t s ]
                prin pad t 10
            ]
            print "|"
        ]
        print h
    ]
]

if e = 0[e: 7] can be removed, right? You use e: 1 + c/weekday % 7, so e will always be in the range [1, 7].

@KevinCruijssen: Maybe I'm missing something, but I think that I need it. Red indexing is 1-based. Please take a look at this:

c: now/time/date

== 12-Oct-2018

c: c + 1

== 13-Oct-2018

1 + c/weekday % 7

== 0; >> 1 + 2 * 3 is 9 in Red, not 7

EDIT: Ah, nvm.. The 1 +  happens first.. Ok, I see my error. I'm used to % and / having operator precedence over +.

@KevinCruijssen Yes, exactly. There's no operator precedence in Red, one needs to use () instead

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Arbitrary Length Hashing
Consider you have a hash function \$\mathcal{H}\$ which takes strings of length \$2n\$ and returns strings of length \$n\$ and has the nice property that it is collision resistant, i.e. it is hard to find two different strings \$s \neq s'\$ with the same hash \$\mathcal{H}(s) = \mathcal{H}(s')\$.
You would now like to build a new hash function \$\mathcal{H'}\$ which takes strings of arbitrary length and maps them to strings of length \$n\$, while still being collision resistant.
Lucky for you, already in 1979 a method now known as the Merkle–Damgård construction was published which achieves exactly this.
The task of this challenge will be to implement this algorithm, so we'll first have a look at a formal description of the Merkle–Damgård construction, before going through a step-by-step example which should show that the approach is simpler than it might appear at first.

Given some integer \$n > 0\$, a hash function \$\mathcal{H}\$ as
described above and an input string \$s\$ of arbitrary
length, the new hash function \$\mathcal{H'}\$ does the following:

Set \$ l = |s|\$, the length of \$s\$, and split \$s\$ in chunks of length \$n\$, filling up the last chunk with trailing zeros if
necessary. This yields \$m = \lceil \frac{l}{n} \rceil \$ many chunks
which are labeled \$c_1, c_2, \dots, c_m \$.
Add a leading and a trailing chunk \$c_0\$ and \$c_{m+1}\$, where \$c_0\$ is a string consisting of \$n\$ zeros and \$c_{m+1}\$ is \$n\$ in binary, padded with leading zeros to length \$n\$.
Now iteratively apply \$\mathcal{H}\$ to the current chunk \$c_i\$ appended to the previous result \$r_{i-1}\$: \$ r_i =
 \mathcal{H}(r_{i-1}c_i)\$, where \$r_0 = c_0\$. (This step might be
more clear after looking at the example below.)
The output of \$\mathcal{H'}\$ is the final result \$r_{m+1}\$.

The Task
Write a program or function which takes as input a positive integer \$n\$, a hash function \$\mathcal{H}\$ as black box and a non-empty string \$s\$ and returns the same result as \$\mathcal{H'}\$ on the same inputs.
This is code-golf, so the shortest answer in each language wins.
Example
Let's say \$n = 5\$, so our given hash function \$\mathcal{H}\$ takes strings of length 10 and returns strings of length 5.

Given an input of \$s = \texttt{"Programming Puzzles"} \$, we get the following chunks: \$s_1 = \texttt{"Progr"} \$, \$s_2 = \texttt{"ammin"} \$, \$s_3 = \texttt{"g Puz"} \$ and \$s_4 = \texttt{"zles0"} \$. Note that \$s_4\$ needed to be padded to length 5 with one trailing zero.
\$ c_0 = \texttt{"00000"}\$ is just a string of five zeros and \$ c_5 = \texttt{"00101"}\$ is five in binary (\$\texttt{101}\$), padded with two leading zeros.
Now the chunks are combined with \$\mathcal{H}\$:
\$r_0 = c_0 = \texttt{"00000"} \$
\$ r_1 = \mathcal{H}(r_0c_1) = \mathcal{H}(\texttt{"00000Progr"})\$
\$ r_2 = \mathcal{H}(r_1c_2) = \mathcal{H}(\mathcal{H}(\texttt{"00000Progr"})\texttt{"ammin"})\$
\$ r_3 = \mathcal{H}(r_2c_3) = \mathcal{H}(\mathcal{H}(\mathcal{H}(\texttt{"00000Progr"})\texttt{"ammin"})\texttt{"g Puz"})\$
\$ r_4 = \mathcal{H}(r_3c_4) = \mathcal{H}(\mathcal{H}(\mathcal{H}(\mathcal{H}(\texttt{"00000Progr"})\texttt{"ammin"})\texttt{"g Puz"})\texttt{"zles0"})\$
\$ r_5 = \mathcal{H}(r_4c_5) = \mathcal{H}(\mathcal{H}(\mathcal{H}(\mathcal{H}(\mathcal{H}(\texttt{"00000Progr"})\texttt{"ammin"})\texttt{"g Puz"})\texttt{"zles0"})\texttt{"00101"})\$
\$r_5\$ is our output.

Let's have a look how this output would look depending on some choices1 for \$\mathcal{H}\$:

If \$\mathcal{H}(\texttt{"0123456789"}) = \texttt{"13579"}\$, i.e. \$\mathcal{H}\$ just returns every second character, we get:
\$r_1 = \mathcal{H}(\texttt{"00000Progr"}) = \texttt{"00Por"}\$
\$r_2 = \mathcal{H}(\texttt{"00Porammin"}) = \texttt{"0oamn"}\$
\$r_3 = \mathcal{H}(\texttt{"0oamng Puz"}) = \texttt{"omgPz"}\$
\$r_4 = \mathcal{H}(\texttt{"omgPzzles0"}) = \texttt{"mPze0"}\$
\$r_5 = \mathcal{H}(\texttt{"mPze000101"}) = \texttt{"Pe011"}\$
So \$\texttt{"Pe011"}\$ needs to be the output if such a \$\mathcal{H}\$ is given as black box function.
If \$\mathcal{H}\$ simply returns the first 5 chars of its input, the output of \$\mathcal{H'}\$ is \$\texttt{"00000"}\$. Similarly if \$\mathcal{H}\$ returns the last 5 chars, the output is \$\texttt{"00101"}\$.
If \$\mathcal{H}\$ multiplies the character codes of its input and returns the first five digits of this number, e.g. \$\mathcal{H}(\texttt{"PPCG123456"}) = \texttt{"56613"}\$, then \$\mathcal{H}'(\texttt{"Programming Puzzles"}) = \texttt{"91579"}\$.

1 For simplicity, those \$\mathcal{H}\$ are actually not collision resistant, though this does not matter for testing your submission.

Sandbox (deleted)

I must say it's fun that the example given has the last 'full' hash be of "OMG Puzzles!" effectively omgPzzles0. Well chosen example input!

Can we assume some flexibility on the input format for H (e.g. it takes two strings of length n, or a longer string of which it only considers the first 2n characters)?

Are space characters, e.g., between "g P" valid output?

@guest271314 If the space is part of the resulting hash, it needs to be outputted. If the hash is actually "gP", you may not output a space inbetween.

@Delfad0r I'd rather say no, because H is a black-box function from which you only know it takes strings of a certain length and returns strings of half the length. So other assumptions like H ignores all but the first n bytes of the string should not be made.

Haskell, 91 90 86 bytes

-1 byte thanks to Laikoni
-4 bytes thanks to xnor

n!h|let a='0'<$[1..n];c?""=c;c?z=h(c++take n(z++a))?drop n z=h.(++mapM(:"1")a!!n).(a?)

Try it online!
Explanation
a='0'<$[1..n]

Just assigns the string "00...0" ('0' \$n\$ times) to a

c?""=c
c?z=h(c++take n(z++a))?drop n z

The function ? implements the recursive application of h: c is the hash we have obtained so far (length \$n\$), z is the rest of the string. If z is empty then we simply return c, otherwise we take the first \$n\$ characters of z (possibly padding with zeros from a), prepend c and apply h. This gives the new hash, and then we call ? recursively on this hash and the remaining characters of z.

n!h=h.(++mapM(:"1")a!!n).(a?)

The function ! is the one actually solving the challenge. It takes n, h and s (implicit) as inputs. We compute a?s, and all we have to do is append n in binary and apply h once more. mapM(:"1")a!!n returns the binary representation of \$n\$.

let in a guard is shorter than using where: Try it online!

It looks like mapM(\_->"01")a can be mapM(:"1")a.

R, 159 154 bytes
function(n,H,s,`?`=paste0,`*`=strrep,`/`=Reduce,`+`=nchar,S=0*n?s?0*-(+s%%-n)?"?"/n%/%2^(n:1-1)%%2)(function(x,y)H(x?y))/substring(S,s<-seq(,+S,n),s--n-1)

Try it online!
Yuck! Answering string challenges in R is never pretty, but this is horrible. This is an instructive answer on how not to write "normal" R code...
Thanks to nwellnhof for fixing a bug, at a cost of 0 bytes!
Thanks to J.Doe for swapping the operator aliasing to change the precedence, good for -4 bytes.
The explanation below is for the previous version of the code, but the principles remain the same.
function(n,H,s,               # harmless-looking function arguments with horrible default arguments
                              # to prevent the use of {} and save two bytes
                              # then come the default arguments,
                              # replacing operators as aliases for commonly used functions:
 `+`=paste0,                  # paste0 with binary +
 `*`=strrep,                  # strrep for binary *
 `/`=Reduce,                  # Reduce with binary /
 `?`=nchar,                   # nchar with unary ?
 S=                           # final default argument S, the padded string:
  0*n+                        # rep 0 n times
  s+                          # the original string
  0*-((?s)%%-n)+              # 0 padding as a multiple of n
  "+"/n%/%2^(n:1-1)%%2)       # n as an n-bit number
                              # finally, the function body:
 (function(x,y)H(x+y)) /      # Reduce/Fold (/) by H operating on x + y
  substring(S,seq(1,?S,n),seq(n,?S,n))  # operating on the n-length substrings of S

I think 0*(n-(?s)%%n) doesn't work if n divides s evenly. But 0*-((?s)%%-n) should work.

@nwellnhof ah, of course, thank you, fixed.

Minor changes, 155 bytes

@J.Doe nice! I saved another byte since seq has 1 as its from argument by default.

C (gcc), 251 bytes
#define P sprintf(R,
b(_){_=_>1?10*b(_/2)+_%2:_;}f(H,n,x)void(*H)(char*);char*x;{char R[2*n+1],c[n+1],*X=x;P"%0*d",n,0);while(strlen(x)>n){strncpy(c,x,n);x+=n;strcat(R,c);H(R);}P"%s%s%0*d",R,x,n-strlen(x),0);H(R);P"%s%0*d",R,n,b(n));H(R);strcpy(X,R);}

Try it online!
Not as clean as the bash solution, and highly improvable.
The function is f taking H as a function that replaces its string input with that string's hash, n as in the description, and x the input string and output buffer.
Description:
#define P sprintf(R,     // Replace P with sprintf(R, leading to unbalanced parenthesis
                         // This is replaced and expanded for the rest of the description
b(_){                    // Define b(x). It will return the integer binary expansion of _
                         // e.g. 5 -> 101 (still as integer)
  _=_>1?                 // If _ is greater than 1
    10*b(_/2)+_%2        // return 10*binary expansion of _/2 + last binary digit
    :_;}                 // otherwise just _
f(H,n,x)                 // Define f(H,n,x)
  void(*H)(char*);       // H is a function taking a string
  char*x; {              // x is a string
  char R[2*n+1],c[n+1],  // Declare R as a 2n-length string and c as a n-length string
  *X=x;                  // save x so we can overwrite it later
  sprintf(R,"%0*d",n,0); // print 'n' 0's into R
  while(strlen(x)>n){    // while x has at least n characters
    strncpy(c,x,n);x+=n; // 'move' the first n characters of x into c
    strcat(R,c);         // concatenate c and R
    H(R);}               // Hash R
  sprintf(R,"%s%s%0*d"   // set R to two strings concatenated followed by some zeroes
    R,x,                 // the two strings being R and (what's left of) x
    n-strlen(x),0);      // and n-len(x) zeroes
  H(R);                  // Hash R
  sprintf(R,"%s%*d",R,n, // append to R the decimal number, 0 padded to width n
    b(n));               // The binary expansion of n as a decimal number
  H(R);strcpy(X,R);}     // Hash R and copy it into where x used to be

229 bytes

I think: 227 bytes (going off of ceilingcat's comment)

Ruby, 78 bytes
->n,s,g{(([?0*n]*2*s).chop.scan(/.{#{n}}/)+["%0#{n}b"%n]).reduce{|s,x|g[s+x]}}

Try it online!
How it works:
([?0*n]*2*s).chop    # Padding: add leading and trailing
                     # zeros, then remove the last one
.scan(/.{#{n}}/)     # Split the string into chunks
                     # of length n
+["%0#{n}b"%n]       # Add the trailing block
.reduce{|s,x|g[s+x]} # Apply the hashing function
                     # repeatedly

Jelly, 23 bytes
0Ṿ;s;BṾ€ṚWƲ}z”0ZU0¦;Ç¥/

Try it online!
Accepts \$\mathcal H\$ at the line above it, \$s\$ as its left argument, and \$n\$ as its right argument.

Bash, 127-ε bytes
Z=`printf %0*d $1` R=$Z
while IFS= read -rn$1 c;do R=$R$c$Z;R=`H<<<${R::2*$1}`;done
H< <(printf $R%0*d $1 `bc <<<"obase=2;$1"`)

Try it online!
This works as a program/function/script/snippet. H must be resolveable to a program or function that will perform the hashing. N is the argument. Example call:
$ H() {
>   sed 's/.\(.\)/\1/g'
> }
$ ./wherever_you_put_the_script.sh 5 <<< "Programming Puzzles"  # if you add a shebang
Pe011

Description:
Z=`printf %0*d $1`

This creates a string of $1 zeroes. This works by calling printf and telling it to print an integer padded to extra argument width. That extra argument we pass is $1, the argument to the program/function/script which stores n.
R=$Z

This merely copies Z, our zero string, to R, our result string, in preparation for the hashing loop.
while IFS= read -rn$1 c; do

This loops over the input every $1 (n) characters loading the read characters into c. If the input ends then c merely ends up too short. The r option ensures that any special characters in the input don't get bash-interpreted. This is the -ε in the title - that r isn't strictly necessary, but makes the function more accurately match the input.
R=$R$c$Z

This concatenates the n characters read from input to R along with zeroes for padding (too many zeroes for now).
R=`H<<<${R::2*$1}`;done

This uses a here string as input to the hash function. The contents ${R::2*$1} are a somewhat esoteric bash parameter substitution which reads: R, starting from 0, only 2n characters.
Here the loop ends and we finish with:
H< <(printf $R%0*d $1 `bc <<<"obase=2;$1"`)

Here the same format string trick is used to 0 pad the number. bc is used to convert it to binary by setting the output base (obase) to 2. The result is passed to the hash function/program whose output is not captured and thus is shown to the user.

Why "127-ε"? Why not just "127"?

I don't know. I was on the fence about the necessity of the r flag. I figured 1 byte doesn't really matter, but if pushed I could shave it.

For the read command?

Because without it a \ in the input will be interpreted instead of ignored, so they'd have to be escaped.

Maybe add a note about that?

I did, in the description for the read command.

It's just not obvious from the title or first few lines.

Perl 6, 79 68 bytes
{reduce &^h o&[~],comb 0 x$^n~$^s~$n.fmt("%.{$n-$s.comb%-$n}b"): $n}

Try it online!
Explanation
{
  reduce         # Reduce with
    &^h o&[~],   # composition of string concat and hash function
    comb         # Split string
      0 x$^n     # Zero repeated n times
      ~$^s       # Append input string s
      ~$n.fmt("  # Append n formatted
        %.       # with leading zeroes,
        {$n             # field width n for final chunk
         -$s.comb%-$n}  # -(len(s)%-n) for padding,
        b")      # as binary number
      :          # Method call with colon syntax
      $n         # Split into substrings of length n
}

Pyth, 24 bytes
Since Pyth doesn't allow H to be used for a function name, I use y instead.
uy+GH+c.[E=`ZQQ.[ZQ.BQ*Z

Try it online! Example is with the "every second character" version of H.

GolfScript, 47 bytes
~:π'0'*:s\+s+π/);[sπ2base{48+}%+0π->]+{+1$~}*\;

Try it online!

Clean, 143 bytes
import StdEnv
r=['0':r]
$n h s=foldl(\a b=h(a++b))(r%(1,n))([(s++r)%(i,i+n-1)\\i<-[0,n..length s]]++[['0'+toChar((n>>(n-p))rem 2)\\p<-[1..n]]])

Try it online!

oK, 41 bytes
{(x#48)(y@,)/(0N,x)#z,,/$((x+x!-#z)#2)\x}

Try it online!
{                                       } /x is n, y is H, z is s.
                          (x+x!-#z)       /number of padding 0's needed + x
                         (         #2)\x  /binary(x) with this length
                      ,/$                 /to string
                    z,                    /append to z
             (0N,x)#                      /split into groups of length x
       (y@,)/                             /foldl of y(concat(left, right))...
 (x#48)                                   /...with "0"*x as the first left string

Python 2, 126 113 bytes
lambda n,H,s:reduce(lambda x,y:H(x+y),re.findall('.'*n,'0'*n+s+'0'*(n-len(s)%n))+[bin(n)[2:].zfill(n)])
import re

Try it online!
-13 thanks to Triggernometry.
Yeah, this is an abomination, why can't I just use a built-in to split a string into chunks...? :-(

https://codegolf.stackexchange.com/a/173952/55696 A while loop is the best builtin I could hope for. 104 bytes

@StevenH. Yeah, especially if you're actually focusing on the golfing itself. >_>

'0'*~-n instead of '0'*(len(s)%n) is shorter (and actually correct for shorter inputs).

@nwellnhof Yeah, but it's definitely not the same thing.

Maybe I wasn't clear enough. Your solution gives the wrong answer for strings like Programming Puzz (16 chars). Replacing '0'*(len(s)%n) with '0'*~-n fixes that and saves 7 bytes.

@nwellnhof Ah, yep, applied a little patch over there, I'll have to test your suggestion a bit though.

Python 2, 106 102 bytes
For once, the function outgolfs the lambda. -4 bytes for simple syntax manipulation, thanks to Jo King.

def f(n,H,s):
 x='0'*n;s+='0'*(n-len(s)%n)+bin(n)[2:].zfill(n)
 while s:x=H(x+s[:n]);s=s[n:]
 return x

Try it online!

Shouldn't the result be 'Pe011', not 'e011'?

That it should. Fixed!

Use semi-colons instead of newlines. -4 bytes

I didn't realize that worked for while loops as well, thanks!

Japt, 27 bytes
òV ú'0 pV¤ùTV)rÈ+Y gOvW}VçT

Try it!
I haven't found any capability for Japt to take functions directly as an input, so this takes a string which is interpreted as Japt code and expects it to define a function. Specifically, OvW takes the third input and interprets it as Japt, then g calls it. Replacing that with OxW allows input as a Javascript function instead, or if the function were (somehow) already stored in W it could just be W and save 2 bytes. The link above has the worked example of \$\mathcal{H}\$ that takes characters at odd indexes, while this one is the "multiply char-codes and take the 5 highest digits" example.
Due to the way Japt takes inputs, \$s\$ will be U, \$n\$ will be V, and \$\mathcal{H}\$ will be W
Explanation:
òV                             Split U into segments of length V
   ú'0                         Right-pad the short segment with "0" to the same length as the others
       p     )                 Add an extra element:
        V¤                       V as a base-2 string
          ùTV                    Left-pad with "0" until it is V digits long
              r                Reduce...
                        VçT          ...Starting with "0" repeated V times...
               È       }                                                  ...By applying:
                +Y               Combine with the previous result
                   gOvW          And run W as Japt code

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Can the number be split into powers of 2?
Yesterday while playing with my kid I noticed the number in his toy train:

So we have $$4281$$ that can be split into $$4-2-8-1$$ or $$2^2-2^1-2^3-2^0$$
So simple challenge: given a non-negative number as input, return consistent truthy and falsey values that represent whether or not the string representation of the number (in base 10 and without leading zeroes) can be somehow split into numbers that are powers of 2.
Examples:
4281      truthy (4-2-8-1)
164       truthy (16-4 or 1-64)
8192      truthy (the number itself is a power of 2)
81024     truthy (8-1024 or 8-1-02-4)
101       truthy (1-01)
0         falsey (0 cannot be represented as 2^x for any x)
1         truthy
3         falsey
234789    falsey
256323    falsey (we have 256 and 32 but then 3)
8132      truthy (8-1-32)

Tests for very large numbers (not really necessary to be handled by your code):
81024256641116  truthy (8-1024-256-64-1-1-16)
64512819237913  falsey

This is code-golf, so may the shortest code for each language win!

@StewieGriffin initially I thought about limiting the input number to the range of a standard int type (4 bytes), but actually I do not mind if your code does not support very large numbers. Just state in your answer the limitations of your code.

Suggested test case: 101 (falsy because of the 0) ... or should this still be true (1 - 01)?

@ShieruAsakoto I've been testing the 101 case with the current answers and they all return true, because it can be splitted into 1-01 that are both powers of 2, so I'll consider that case to be truthy.

Just leaving this here as tip for everyone. Here are three possible ways to check if a number is a power of 2: 1) Check if log2(n) doesn't contain decimal digits after the comma. 2) Check if n AND (n-1) == 0. 3) Create a list of square-nrs and check if n is in that list.

"square-nrs" should be "powers of 2" in my comment above of course.. >.>

Related

Similar question

Should the code only work for powers of 2 that are a natural number? Like, 0.25 = 2^-2?

@Nzall no, only non-negative integers are needed for this challenge.

Actually, 01 is not a proper number.

05AB1E, 9 8 bytes
Ýos.œåPZ

-1 byte thanks to @Emigna by using Z (max) for the list of 0s and 1s to mimic an any command for 1 (truthy).
Try it online or verify all test cases. (NOTE: The т in the header is 100 to only get the first 100 power of 2 numbers, instead of the first input amount of power of 2 numbers. It works with the input amount of power of 2 as well, but is pretty inefficient and might timeout on TIO if the input is large enough.)
Explanation:
Ý            # Create a list in the range [0,n], where n is the (implicit) input
             # (or 100 in the TIO)
             #  i.e. 81024 → [0,1,2,3,...,81024]
 o           # Raise 2 to the `i`'th power for each `i` in the list
             #  → [1,2,4,8,...,451..216 (nr with 24391 digits)]
  s          # Swap to take the input
   .œ        # Create each possible partition of this input
             #  i.e. 81024 → [["8","1","0","2","4"],["8","1","0","24"],...,["8102","4"],["81024"]]
     å       # Check for each if it's in the list of powers of 2
             #  → [[1,1,0,1,1],[1,1,0,0],...,[0,1],[0]]
      P      # Check for each inner list whether all are truthy
             #  → [0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0]
       Z     # Take the maximum (and output implicitly)
             #  → 1 (truthy)

Nice, my solution was .œ.²1%O0å (9 bytes as well). Mine failed 0, however.

@Mr.Xcoder Ah, .²1%O0 is pretty smart as well. I thought about using log2 like this .²DïQ, but it would require a map around it to do this for each number, and it indeed didn't work for edge-case 0.

JavaScript (Node.js), 54 bytes
f=(v,o=10)=>v&v-1|!v?v>o?f(v%o)&f(v/o|0)|f(v,o*10):0:1

Try it online!

JavaScript (Node.js), 69 64 58 bytes
f=(x,m=10,q=!(x%m&x%m-1|!x))=>x<m?q:q&&f(x/m|0)||f(x,10*m)

Try it online!
Input as number. The logic part is quite convoluted, so no idea how to untangle it and get rid of q.
-11 bytes by golfing the power-of-2 check.

Jelly, 9 bytes
ŒṖḌl2ĊƑ€Ẹ

Check out the test suite!

Alternative
Doesn't work for the large test cases due to precision issues.
ŒṖḌæḟƑ€2Ẹ

Check out the test suite!
How?
Program I
ŒṖḌl2ĊƑ€Ẹ     Full program. N = integer input.
ŒṖ            All possible partitions of the digits of N.
  Ḍ           Undecimal (i.e. join to numbers).
   l2         Log2. Note: returns (-inf+nanj) for 0, so it doesn't fail.
     ĊƑ€      For each, check if the logarithm equals its ceil.
        Ẹ     Any. Return 0 if there are no truthy elements, 1 otherwise.

Program II
ŒṖḌæḟƑ€2Ẹ     Full program. N = integer input.
ŒṖ            All possible partitions of the digits of N.
  Ḍ           Undecimal (i.e. join to numbers).
     Ƒ€       For each partition, check whether its elements are invariant under...
   æḟ  2      Flooring to the nearest power of 2.
        Ẹ     Any. Return 0 if there are no truthy elements, 1 otherwise.

JavaScript (Node.js), 75 69 bytes
-6 bytes thanks @Arnauld. At most 32-bit support
f=x=>+x?[...x].some((_,i)=>(y=x.slice(0,++i))&~-y?0:f(x.slice(i))):!x

Try it online!
Input as a string.

Python 2, 72 70 bytes
f=lambda n,m=10:n>=m/10and(n%m&n%m-1<1and(n/m<1or f(n/m))or f(n,m*10))

Try it online!

JavaScript, 59 bytes
s=>eval(`/^(${(g=x=>x>s?1:x+'|0*'+g(x+x))(1)})+$/`).test(s)

Try it online!
Builds a regex like /^(1|0*2|0*4|0*8|0*16|0*32|…|0*1)+$/ of powers of 2, and tests it on s.
Only works up to the precision of JavaScript numbers, of course: eventually the terms in the regex will look like 1.2345678e30 (or Inf). But since powers of 2 are easy to represent accurately in floating-point, they'll never be wrong integers, which would be more disqualifying, I think.
@tsh saved 14 bytes. Neato!

59 bytes

Python 2, 85 bytes
f=lambda n:bin(int(n)).count('1')==1or any(f(n[:i])*f(n[i:])for i in range(1,len(n)))

Try it online!

Perl 6, 28 24 23 bytes
-4 bytes thanks to Jo King
{?/^[0*@(2 X**^32)]+$/}

Try it online!
Handles powers up to 231.

24 bytes by moving the 0* out of the interpolated part

APL(NARS), 154 chars, 308 bytes
∇r←f w;g;b;z;k
   g←{⍵≤0:1⋄t=⌊t←2⍟⍵}⋄→A×⍳∼w≤9⋄r←g w⋄→0
A: z←w⋄b←0⋄k←1
B: b+←k×10∣z⋄z←⌊z÷10
   →C×⍳∼g b⋄r←∇z⋄→0×⍳r
C: k×←10⋄→B×⍳z≠0
   r←0
∇
h←{⍵=0:0⋄f ⍵}

The function for the exercise it is h. The algorithm not seems exponential or factorial... test:
  h¨ 4281 164 8192 81024 101
1 1 1 1 1
  h¨ 0 1 3 234789 256323 8132
0 1 0 0 0 1
  h 81024256641116
1
  h 64512819237913
0

Python 2, 57 bytes
f=lambda n,k=10:k<11*n>n%k&n%k-1<(n<k)|f(n/k)|f(n,10*k)*n

Try it online!

Python 2, 86 bytes
lambda n:re.match('^(%s)*$'%'|'.join('0*'+`1<<k`for k in range(n)),`n`)and 0;import re

Try it online!

Ruby, 55 bytes
->n{a=*b=1;a<<b*=2until b>n;n.to_s=~/^(0*(#{a*?|}))*$/}

Try it online!
Output is 0 if true and nil if false.

Ruby, 49 bytes
->n{n.to_s=~/^(0*(#{(0..n).map{|x|2**x}*?|}))*$/}

Try it online!
Only works in theory. Takes forever for large values of n

Red, 212 211 bytes
func[n][g: func[x][(log-2 do x)% 1 = 0]repeat i 2 **((length? s: form n)- 1)[b: a:
copy[] k: i foreach c s[append b c if k % 2 = 0[alter a g rejoin b
b: copy[]]k: k / 2]append a g form c if all a[return on]]off]

Try it online!
Another long submission, but I'm not comletely dissatisfied, because there is no built-in for finding all substrings in Red.
More readable:
f: func [ n ] [
    g: func [ x ] [ (log-2 do x) % 1 = 0 ]
    repeat i 2 ** ((length? s: form n) - 1) [
        b: a: copy []
        k: i
        foreach c s [
            append b c
            if k % 2 = 0 [
                append a g rejoin b
                b: copy []
            ]
            k: k / 2
        ]
        append a g form c
        if all a[ return on ]
    ]
    off
]

PHP, 101 bytes
Can´t seem to get this below 100; but I could get it to 100 if 101 was a falsy case.
function f($s){for($x=.5;$s>=$x*=2;)if(preg_match("/^$x(.*)$/",$s,$m)?!~$m[1]||f(+$m[1]):0)return 1;}

returns \$NULL\$ for falsy and \$1\$ for truthy.
Try it online.
variations:
for($x=.5;$s>=$x*=2;)
while($s>=$x=1<<$i++)   # yields notices "undefined variable $i"

?!~$m[1]||f(+$m[1]):0
?~$m[1]?f(+$m[1]):1:0

PHP 5 or older, 95 bytes
function f($s){while($s>=$x=1<<$i++)if(ereg("^$x(.*)$",$s,$m)?$m[1]>""?f(+$m[1]):1:0)return 1;}

Axiom, 198 bytes
G(a)==(a<=1=>2>1;x:=log_2 a;x=floor x)
F(n)==(n<=9=>G n;z:=n;b:=0;k:=1;repeat(b:=b+k*(z rem 10);z:=z quo 10;if G b and F z then return 2>1;k:=k*10;z<=0=>break);1>1)
H(n:NNI):Boolean==(n=0=>1>1;F n)

ungolf and test
g(a)==(a<=1=>2>1;x:=log_2 a;x=floor x)
f(n)==
   n<=9=>g n
   z:=n;b:=0;k:=1
   repeat
      b:=b+k*(z rem 10);z:=z quo 10;
      if g b and f z then return 2>1
      k:=k*10
      z<=0=>break
   1>1
h(n:NNI):Boolean==(n=0=>1>1;f n)

(15) -> [[i,h i] for i in [4281,164,8192,81024,101]]
   (15)  [[4281,true],[164,true],[8192,true],[81024,true],[101,true]]
                                                      Type: List List Any
(16) -> [[i,h i] for i in [0,1,3,234789,256323,8132]]
   (16)  [[0,false],[1,true],[3,false],[234789,false],[256323,false],[8132,true]]
                                                      Type: List List Any
(17) -> [[i,h i] for i in [81024256641116, 64512819237913]]
   (17)  [[81024256641116,true],[64512819237913,false]]
                                                      Type: List List Any
(18) -> h 44444444444444444444444444
   (18)  true
                                                            Type: Boolean
(19) -> h 44444444444444444128444444444
   (19)  true
                                                            Type: Boolean
(20) -> h 4444444444444444412825444444444
   (20)  false
                                                            Type: Boolean
(21) -> h 2222222222222244444444444444444412822222222222210248888888888882048888888888888888
   (21)  true
                                                            Type: Boolean
(22) -> h 222222222222224444444444444444441282222222222225128888888888882048888888888888888
   (22)  true
                                                            Type: Boolean

Powershell, 56 bytes
$x=(0..63|%{1-shl$_})-join'|0*'
"$args"-match"^(0*$x)+$"

Test script:
$f = {

    $x=(0..63|%{1-shl$_})-join'|0*'
    "$args"-match"^(0*$x)+$"

}

@(
    ,(4281            ,$true)
    ,(164             ,$true)
    ,(8192            ,$true)
    ,(81024           ,$true)
    ,(101             ,$true)
    ,(0               ,$false)
    ,(1               ,$true)
    ,(3               ,$false)
    ,(234789          ,$false)
    ,(256323          ,$false)
    ,(8132            ,$true)
    ,("81024256641116"  ,$true)
    ,("64512819237913"  ,$false)
) | % {
    $n, $expected = $_
    $result = &$f $n
    "$($result-eq$expected): $result <- $n"
}

Output:
True: True <- 4281
True: True <- 164
True: True <- 8192
True: True <- 81024
True: True <- 101
True: False <- 0
True: True <- 1
True: False <- 3
True: False <- 234789
True: False <- 256323
True: True <- 8132
True: True <- 81024256641116
True: False <- 64512819237913

Explanation:
Builds a regex like ^(0*1|0*2|0*4|0*8|0*16|0*32|…)+$ of powers of 2, and tests it on arguments.

POSIX ERE, 91 bytes
(0*([1248]|16|32|64|128|256|512|1024|2048|4096|8192|16384|32768|65536|131072|262144|524288))+

This is totally cheating, based on the text large numbers (not really necessary to be handled by your code) in the question; it handles all values in the size range of the examples. Obviously can be extended up to full range of 32- or 64-bit integer types at the expense of size. I mainly wrote it as a demonstration of how the problem naturally fits the tool. A fun exercise would be rewriting it as a program that generates the ERE for arbitrary range then matches against it.

Japt -!, 12 bytes
Takes input as a string.
ÊÆòXÄÃex_&ZÉ

Try it

The 0 case outputs true and hence cases such as 1010 also output true.

C# 157 bytes
bool P(string s,int i=1)=>i>=s.Length?((Func<ulong,bool>)((x)=>(x!=0)&&((x&(x-1))==0)))(ulong.Parse(s)):(P(s,i+1)||(P(s.Substring(0,i))&&P(s.Substring(i))));

You can Try it online

APL(NARS), 70 chars, 140 bytes
P←{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}
f←{⍵=0:0⋄∨/∧/¨y=⌊y←2⍟⍎¨¨P⍕⍵}

test:
  f¨ 4281 164 8192 81024 101
1 1 1 1 1
  f¨ 0 1 3 234789 256323 8132
0 1 0 0 0 1
  f 126
0

i not try to do other more big numbers...
i have to note that P is not normal partition, but it is one partition
where all element are subset that have member all consecutive, for example
  ⎕fmt P 'abc'
┌4──────────────────────────────────────────────────┐
│┌1─────┐ ┌2─────────┐ ┌2─────────┐ ┌3─────────────┐│
││┌3───┐│ │┌2──┐ ┌1─┐│ │┌1─┐ ┌2──┐│ │┌1─┐ ┌1─┐ ┌1─┐││
│││ abc││ ││ ab│ │ c││ ││ a│ │ bc││ ││ a│ │ b│ │ c│││
││└────┘2 │└───┘ └──┘2 │└──┘ └───┘2 │└──┘ └──┘ └──┘2│
│└∊─────┘ └∊─────────┘ └∊─────────┘ └∊─────────────┘3
└∊──────────────────────────────────────────────────┘

note that is absent the element ((ac) (b)) or better ,,¨('ac')'b'
  ⎕fmt ,,¨('ac')'b'
┌2─────────┐
│┌2──┐ ┌1─┐│
││ ac│ │ b││
│└───┘ └──┘2
└∊─────────┘

C (gcc), -DA=asprintf(&c, + 108 = 124 bytes
p,c;f(a,i){c="^(0*(1";for(i=0;i<31;)A"%s|%d",c,1<<++i);A"%s))+$",c);regcomp(&p,c,1);a=!regexec(&p,a,0,0,0);}

Try it online!
This builds a regex of the powers of 2 up to 2**32, and then matches the input string against it.

JavaScript (Node.js), 56 bytes
f=(x,c=v=1)=>x<v?x.match('^('+c+')+$'):f(x,c+'|'+(v*=2))

Try it online!


text:
Longest Seven Segment Word
This question was inspired by Tom Scott's video here.
The English language has plenty of words, but what's the longest one that can be displayed on a seven segment display? Your challenge is given a list of letters that may not be displayed, display the longest English word in a 7 segment display format?
Input

Input will contain a series of unacceptable characters. (letters that you are not permitted to use in your word.)
Input can be taken from one of the following:

stdin
command-line arguments
function arguments

Output

Output the longest word using the provided alphabet from the input. (In the case of 2 words of the same length, the one that comes first is the "longest". When a hyphen is in the word, it counts towards its length, but is not displayed.)
Output must be formatted like a 7 segment display, see the rules below for more about the format.
Output must be in stdout or closest equivalent.
Output may contain a trailing newline character.

Letters

This image shows my source of the alphabet
Here is my simple ascii display so you can visually see the letters (my apologies, the wrap function I used broke with spaces so I had to settle on asterisks).
And here is a table to show the alphabet as well:
  ____  A
 | F  | B
 |    |
  ____  G
 |    |
 | E  | C
  ____  D

ABCDEFG Letter
1110111 a
0011111 b
1001110 c
0111101 d
1001111 e
1000111 f
1011110 g
0010111 h
0000110 i
0111100 j
1010111 k
0001110 l
1010100 m
1110110 n
1111110 o
1100111 p
1110011 q
1100110 r
1011011 s
0001111 t
0111110 u
0111010 v
0101010 w
0110111 x
0111011 y
1101001 z

Rules

Standard loopholes are disallowed HOWEVER words.txt (the dictionary) is the only outside file you may reference (renaming it is not allowed, it must be called words.txt as it is in the repository).
The seven segment display must:

Be an actual seven segment display. (I'm not going to be picky on how it looks, if it was accepted over there then it's accepted over here.)
Have any filler/whitespace character of choice.

Test Cases
Wrapping is an unnecessary challenge and is not needed; I did it out of ease of looking at it in my terminal.
Remember: Your whitespace does not need the same character.
input:
gkmqvwxz

output:
******************____********************____****____****____********
******|**|*******|*******|*******|*******|****|**|****|**|****|*******
******|**|*******|*******|*******|*******|****|**|****|**|****|*******
**____********************____************************************____
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
**____************____************____****____************____****____
************____************____****____****************************__
|**|*******|****|**|*******|*******|****|**|****|**|*******|*******|**
|**|*******|****|**|*******|*******|****|**|****|**|*******|*******|**
************____****____****____************____************____******
|**|*******|*******|****|**|*******|****|*******|**|*******|*******|**
|**|*******|*******|****|**|*******|****|*******|**|*******|*******|**
****************************____************____****____****____******
__************____********************____****____****____****____****
**|**|*******|*******|*******|*******|****|**|****|**|****|**|*******|
**|**|*******|*******|*******|*******|****|**|****|**|****|**|*******|
**********************____************************************____****
*****|*******|*******|****|**|*******|****|**|*******|****|**|*******|
*****|*******|*******|****|**|*******|****|**|*******|****|**|*******|
**************____************____****____************____****____****
****************____****____****____**
*******|*******|****|**|****|**|******
*******|*******|****|**|****|**|******
____****____****____************____**
*******|****|**|****|**|****|**|******
*******|****|**|****|**|****|**|******
____****************************____**

The word should be "dichlorodiphenyltrichloroethane" for debugging purposes.
input:
gkmqvwxzio

output:
**____************____****____****____************____****____****____
*|*******|****|**|****|**|*******|****|**|*******|****|**|****|**|****
*|*******|****|**|****|**|*******|****|**|*******|****|**|****|**|****
**____************____****____************____************____********
******|**|****|**|*******|*******|*******|*******|*******|****|**|****
******|**|****|**|*******|*******|*******|*******|*******|****|**|****
**____****____************____************____************************
****____****____****____****____************____****____************__
|**|*******|*******|*******|****|*******|**|*******|****|**|*******|**
|**|*******|*******|*******|****|*******|**|*******|****|**|*******|**
****____************____************____****____************____******
|*******|**|*******|*******|****|**|****|**|*******|****|**|*******|**
|*******|**|*******|*******|****|**|****|**|*******|****|**|*******|**
****____****____****____************____****____************____******
__****____****____****____**
**|**|*******|*******|******
**|**|*******|*******|******
******____****____****____**
**|**|************|*******|*
**|**|************|*******|*
******____****____****____**

The word should be "supertranscendentness" for debugging purposes.
input:
abcdefghijklm

output:
**********____****____************____********************____****____
*|*******|****|**|****|**|*******|*******|****|**|****|**|****|**|****
*|*******|****|**|****|**|*******|*******|****|**|****|**|****|**|****
**____********************____****____****____************************
*|*******|****|**|****|**|************|*******|**********|****|**|****
*|*******|****|**|****|**|************|*******|**********|****|**|****
**____****____****____****____****____****____****____****____****____
************____**********
|**|*******|*******|****|*
|**|*******|*******|****|*
****____****____****____**
|**|************|*******|*
|**|************|*******|*
****____****____****____**

The word should be "tootsy-wootsy" for debugging purposes. (We do not output the hyphen but it does count towards the length of the word.)
input:
ikmopqsvwz

output:
**____****____****____****____************____****____****____****____
*|*******|****|**|*******|****|**|*******|*******|****|**|****|**|****
*|*******|****|**|*******|****|**|*******|*******|****|**|****|**|****
******************____****____****____********************____********
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
**____************____************____****____************************
********************____************____********************____****__
|*******|*******|**|****|**|****|**|*******|*******|*******|*******|**
|*******|*******|**|****|**|****|**|*******|*******|*******|*******|**
****____****____****____********************____****____****____******
|**|****|**|****|**|****|**|****|**|****|**|****|**|*******|*******|**
|**|****|**|****|**|****|**|****|**|****|**|****|**|*******|*******|**
****____****____************____****____************____****____******
__**
**|*
**|*
****
****
****
****

The word should be "great-granddaughter" for debugging purposes. (We do not output the hyphen but it does count towards the length of the word.)
Scoring
This is code-golf, so the shortest submission (in bytes) wins.
(This is also my first question so tell me if I skipped over something or something is unclear or not. Thanks and good luck!)

As with a lot of challenges involving finding a specific english word, I reccomend the dictionary of words be passed to the program as a list rather thsn be stored somewhere else. This makes it much easier to test

@JoKing So what you mean is it is passed in as a separate argument or input? (If you linked an example that may be helpful for me to get what you are saying.)

For example, Generate a Portmentout

This seems like it would be more appropriate as 2 distinct challenges: (1) given some dictionary, find the longest word not using characters from some set; (2) convert a string of characters in a..z into 7-segment form according to your spec.

As regards the part of the challenge where you seek the longest string in some dictionary which does not contain certain characters: you more generally say to ignore hyphens; so is 're-sort' longer than 'resort', or are they the same length?

@ChasBrown It should have been more clearly stated, what I meant was you are to ignore the hyphens when it is output but 're-sort' is longer than `'resort'``. I will change the phrasing of the question to help remove that confusion.

Need clarification on non-letters: should they A) be skipped in output or B) be assumed blank or C) can we choose?

test case  with "abcdefghijklm" input states than correct word is "tootsy-wootsy". But "Rostov-on-Don" has the same length and comes first. may you to justify that result?

JavaScript, 830 characters, oooooof
Edit: I fixed the issue and ignore my previous edits where I started I found an error, I was sanitizing the dictionary incorrectly. Funny enough, this didn't change the code length
Anyways, someone had to do this challenge. If winning only requires the shortest, it's always possible to win by default, right? :P
var q=new XMLHttpRequest();q.open("get","words.txt");q.onreadystatechange=()=>{if(q.readyState!=4)return;(z=>q.responseText.toLowerCase().split("\n").filter(w=>w.split("").reduce((j,l)=>j&&z.indexOf(l)<0,true)).map((o,p)=>[o,p]).sort((a,b)=>{if(a[0].length == b[0].length){return a[1]-b[1]}return b[0].length-a[0].length;})[0][0].split("").forEach(e=>e=e.replace(/[^a-z]/,"")&&console.log(("ABCEFGCDEFGADEFBCDEGADEFGAEFGACDEFCEFGEFBCDEACEFGDEFACEABCEFABCDEFABEFGABCFGABEFACDFGDEFGBCDEFBCDFBDFBCEFGBCDFGABDG".split("").reduce((f,v,i)=>{if(i==114){f[0].unshift(v);f[1].push(f[0])}else if(v<f[0][0]){f[1].push(f[0]);f[0]=[v]}else{f[0].unshift(v)}return f},[[0],[]])[1][e.charCodeAt()-97]).reduce((f,v)=>f.replace(RegExp(`${v}`,"g"),"#"),"-AAA-\nF---B\nF---B\n-GGG-\nE---C\nE---C\n-DDD-").replace(/[^#\n]/g,"-"))))(prompt())};q.send()

Basically, how it works is, there's an output string that encodes segments for letters, and a format string, that the output string is applied onto.
Here's a version that labels these variables and is a bit less... Harsh.
It skips functions entirely and recalculates variables for any place they are iterated, so it's very inefficient, but it should never take more than a few seconds at worst case to run. Input is given through an html prompt. The script assumes it is part of a window with relative file access and outputs to the console.

const outputString = "ABCEFGCDEFGADEFBCDEGADEFGAEFGACDEFCEFGEFBCDEACEFGDEFACEABCEFABCDEFABEFGABCFGABEFACDFGDEFGBCDEFBCDFBDFBCEFGBCDFGABDG";
const formatString = "-AAA-\nF---B\nF---B\n-GGG-\nE---C\nE---C\n-DDD-";

var q=new XMLHttpRequest();
q.open("get","words.txt");
q.onreadystatechange=()=>{
    if(q.readyState!=4)return;
    (z=>q.responseText.toLowerCase().split("\n").filter(
        w=>w.split("").reduce((j,l)=>j&&z.indexOf(l)<0,true)
    ).map(
        (o,p)=>[o,p]
    ).sort(
        (a,b)=>{
            if(a[0].length == b[0].length){
                return a[1]-b[1]
            }
            return b[0].length-a[0].length;
        }
    )[0][0].split("").forEach(
        e=>e=e.replace(/[^a-z]/,"")&&console.log(
            (outputString.split("").reduce(
                (f,v,i)=>{
                    if(i==114){
                        f[0].unshift(v);f[1].push(f[0])
                    }else if(v<f[0][0]){
                        f[1].push(f[0]);f[0]=[v]
                    }else{
                        f[0].unshift(v)
                    }return f
                },[[0],[]]
            )[1][e.charCodeAt()-97]).reduce(
                (f,v)=>f.replace(RegExp(`${v}`,"g"),"#"),formatString
            ).replace(/[^#\n]/g,"-"))
    ))(prompt())
};
q.send()

These particular seven segment display codes for the alphabet (for example, 0101100) can't overlap when you remove their zeroes. What I mean by that is for each index of the string if you were to encapsulate that spot, chaining all the strings together never results in a case that the last index of a display code is lower than the first index of the following code. This isn't particularly true of all display code permutations and orderings, but in this case it was so we use that.
I haven't double checked because I got so, um, involved in this code, but I think that it might be smaller to store these modified display codes in a flat array than to break them into an array based on one string. But that wasn't as fun.
I don't expect to win, but I am curious if anyone else can beat this in web-oriented JavaScript using an XMLHttpRequest and prompt() for input.

I'd recommend you have a look at the fetch() API.

PHP, 292 bytes
foreach(file("words.txt")as$w)preg_match("%[$argn]%i",$w)||$e<($n=strlen($w=trim($w)))&&$s=strtoupper($w.$e=$n;for($r=["
","
","
"];$i<$e;$b&&$k+=4)for($b=ord("}7f\37vtg5$\17u&Emo|yls6/+*=;Z"[ord($s[$i++])-65]),$p=7;$p--;)$b>>$p&1&&$r[(8-$p)/3][$k+$x="3213212"[$p]]="_|"[$x&1];echo join($r);

Run as pipe with -nr or try it online (with a much smaller dictionary).
In case you run out of memory, replace foreach(file("words.txt")as$w) with for($f=fopen("words.txt",r);$w=fgets($f);). This will also improve performance a lot.
breakdown
foreach(file("words.txt")as$w)      # 1. loop $w through words
    preg_match("%[$argn]%i",$w)||       # if there are forbidden characters, skip
        ($e<$n=strlen($w=trim($w)))     # if length $n exceeds current max length $e
            &&$s=strtoupper($w)             # then update longest word $s
            .$e=$n;                         # and max length
for($r=["\n","\n","\n"];            # 2. init my ouput buffer
    $i<$e;                          # 3. loop through word characters
    $b&&$k+=4)                          # 3. if previous char was legal, increment output offset
    for(                                # 1. get bit mapping for character: (none for non-letters)
        $b=ord("}7f\37vtg5$\17u&Emo|yls6/+*=;Z"[ord($s[$i++])-65]),
        $p=7;$p--;)                     # 2. loop through bits
        $b>>$p&1&&                          # if bit $p is set,
            $r[(8-$p)/3][$k+$x="3213212"[$p]]   # then map bit no. to segment coordinates
                =$x&1?d|t:_;                    # and draw the according character
echo join($r);                      # 4. print my output buffer

notes

I could lose 11 bytes if the dictionary contained only letters, space and linebreaks
OR 12 if only all letters were uppercase. Dang!
I could paint every "longest" word; the last will remain in the buffer for printing; that would mean I wouldn´t have to copy $w to $s and I could copy $n to $e in the character loop, but I would need if(!preg_match(...)&&$e<$n=strlen(...)) and I had to reset $i=$k=0; that would eat up all the savings.
I could do !$i=$k=preg_match(...) but that would require extra parentheses - no savings either.
Makes me almost wish that we also had to paint the digits.
Painting the whole thing into a single string instead of an array would save five bytes in the painting, but cost nine in the output.


text:
Accordion Solitaire: Which First Moves Can I Make?
Introduction:
Unfortunately an Accordion Solitaire Solver challenge already exists (Solve a game of Accordion), so instead this easier related challenge.
Let's start by explaining how Accordion Solitaire works:

You start with all 52 cards (or 53 if you add a Joker) in one big row.
You pile up cards from right to left that are either adjacent, or have two cards in between them.

This can either be when they are the same suit
Or when they have the same value

For example, let's say we start with this: HK S8 SK DK, then you'd have these possible game scenarios:

S8←SK, resulting in HK SK DK; SK←DK, resulting in HK DK; HK←DK, resulting in DK.
SK←DK, resulting in HK S8 DK.
HK←DK, resulting in DK S8 SK; S8←SK, resulting in DK SK; DK←SK, resulting in SK.

You win when every card is in a single pile in the end, so the game scenarios 1 and 3 would be a won Accordion Solitaire, but in scenario 2 you would have lost.
NOTE: Symbols used are as follows: H=Hearts; S=Spades; D=Diamonds; C=Clubs. T=10; J=Jack; Q=Queen; K=King; A=Ace. J=Joker.
PS: Irrelevant for this challenge, but added for informational purposes for those interested: if you play Accordion Solitaire with Jokers, you can only use each Joker once. The Joker will be put at the bottom of the pile when paired up. I.e. H4 C4 S4 J could have for example the following game scenario: S4←J, resulting in H4 C4 S4 (so NOT H4 C4 J); C4←S4 resulting in H4 S4; H4←S4 resulting in S4.
Challenge:
Given a row of cards, output all first steps we can make. So with the example HK S8 SK DK above, the result would be ["S8←SK","SK←DK","HK←DK"].
Challenge rules:

Not all inputs can have a move. So a test case like H3 C7 S5 CQ will result in an empty output, because no moves can be made.
Jokers will be added, which can be used as any wild card, so it can always pair up with up to four other cards (depending on its position).
Input and output formats are flexible, but you'll have to use the formats specific (with optionally 10 instead of T). Input can be a single space-delimited string; list of strings, characters; map with suit + value; etc. Output can be a single delimited string, pairs output to STDOUT, list of pairs, etc. (the character to indicate moves - for which I've used ← in the example above - can also be anything you'd like, and the order of the pairs could also be reversed (i.e. ["SK→S8","DK→SK","DK→HK"])). Please state what you've used in your answer!
Order of the list in the output doesn't matter (i.e. ["SK←DK","S8←SK","HK←DK"] is valid as well).
There won't be any test cases with duplicated cards (including Jokers). So we can assume the test cases use a single Deck of 53 cards (52 + 1 Joker). (So you could use a set instead of list for the output if it would save bytes, since all pairs will be unique.)
You are allowed to use 10 instead of T if that's what you prefer. You are not allowed to use JJ (or anything else of 2 characters) for the Jokers; Jokers will always be a single J.

General rules:

This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code (i.e. TIO).
Also, adding an explanation for your answer is highly recommended.

Test cases:
Input                       Output

"HK S8 SK DK"               ["S8←SK","SK←DK","HK←DK"]
"HA H3 ST"                  ["HA←H3"]
"H3 C7 S5 CQ"               []
"HK S8 J C8 CK"             ["S8←J","J←C8","C8←CA"]
"H5 CA SQ C9 H9 C2 CQ HJ CT SK D3 H8 HA HQ S4 DA H7 SA DK"
                            ["C9←H9","C9←CQ","H9←HJ","C2←CQ","C2←CT","H8←HA","HA←HQ","HA←DA","HQ←H7","S4←SA","DA←DK"]
"CA C2 C3 J H2 H3 D4 H4"    ["CA←C2","CA←J","C2←C3","C2←H2","C3←J","C3←H3","J←H2","J←D4","H2←H3","H2←H4","D4←H4"]
"H4 C4 S4 J"                ["H4←C4","H4←J","C4←S4","S4←J"]
"H3 S3"                     ["H3←S3"]

Can't the CQ be piled onto the C9 or the C2?

@Neil Ah, I somehow completely forgot about the CQ when I created the test case.. Fixed, thanks.

Retina, 60 bytes
L$w`((\bJ)|(\w)(\w)) (\w+ \w+ )?((?(2)..|(J|\3.|.\4)))
$1<$6

Try it online! Link includes test cases. Explanation:
L$
$1<$6

Output the appropriate captures from each match.
w`

Find all overlapping matches (not just simple overlaps).
\b((\bJ)|(\w)(\w)) (\w+ \w+ )?((?(2)..|(J|\3.|.\4)))

Match either the Joker or a two-letter card, then two optional cards, then if the Joker was matched then any other card otherwise either the Joker or a card that matches either in suit or value. (I don't have to check for letters here as there can only be one Joker and the suit and rank can only match another card.)

Nice answer! The only part I don't really understand how it works is ?(2)... Everything else is clear. It checks for each card (((\bJ)|(\w)(\w))) if the one next to it (or optionally with two cards in between ((\w+ \w+ )?)) is a Joker, the same value, or the same suit ((J|\3.|.\4)). But what is the purpose of the ?(2)..? EDIT: I guess it's for when the first card is a Joker?

@KevinCruijssen (?(2)...|...) is conditional regex; it matches the first alternation if $2 was captured previously and the second alternatiion if not. You could probably do something similar with lookarounds, because you can only look for \2 if it matched earlier.

Python 3, 124 119 bytes
lambda c:[[v,c[j]]for i,v in enumerate(c)for j in[i+1,i+3]if j<len(c)and any(d[0]==d[1]or"J"in d for d in zip(v,c[j]))]

Try it online!
Credits

From 124 to 119 bytes by ovs.


text:
Output the anti-clockwise inward spiral of a 2D array
From this stackoverflow question
Given a 2D array of size \$ M \times N \$, output the values in a anti-clockwise fashion. The output must start from the outside to the inside and the initial point always is going to be \$(0,0)\$.
Example Given:
$$ \begin{bmatrix} \color{blue}1&\color{red}2&\color{red}3&\color{red}4 \\ \color{red}5&6&7&\color{red}8 \\ \color{red}9&10&11&\color{red}{12} \\ \color{red}{13}&\color{red}{14}&\color{red}{15}&\color{red}{16}\end{bmatrix} $$
The edge values in counterclockwise is then \$ 1,5,9,13,14,15,16,12,8,4,3,2 \$.
Now we repeat the process for the inner values. This will end up with a matrix like the following
$$ \begin{bmatrix} \color{blue}6&\color{red}7 \\ \color{red}{10}&\color{red}{11} \end{bmatrix}$$
And the inner values is then \$ 6,10,11,7 \$
The final result will be then \$ 1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7 \$

Rules

Assume non-empty input
Assume matrix values as positive integers
Standard I/O Methods apply
Standard code-golf rules and winning criteria apply

Some test cases
Input
[
  [1, 2, 3, 4, 5, 6, 7],
  [8, 9, 10,11,12,13,14],
  [15,16,17,18,19,20,21]
]
Output
1,8,15,16,17,18,19,20,21,14,7,6,5,4,3,2,9,10,11,12,13

--------------------------------------------------------

Input
[
    [1,2,3],
    [3,2,1],
    [4,5,6],
    [6,5,4],
    [7,8,9],
    [9,8,7]
]
Output
1,3,4,6,7,9,8,7,9,4,6,1,3,2,2,5,5,8

-----------------------------------------------------
Input
[
    [1]
]
Output
1
-----------------------------------
Input
[
    [1, 2],
    [2, 1]
]
Output
1,2,1,2
-----------------------------------------------------
Input
[
    [1,2,3,6,7],
    [2,4,3,2,1],
    [3,2,4,5,6],
    [6,5,6,5,4],
    [10,4,7,8,9],
    [12,4,9,8,7]
]
Output
1,2,3,6,10,12,4,9,8,7,9,4,6,1,7,6,3,2,4,2,5,4,7,8,5,5,2,3,4,6

So are we going clockwise or counterclockwise?

@LegionMammal978 counterclockwise (I though it was called anti-clockwise)

Anti- and counter-clockwise are both correct, with each more common in BrEng and AmEng, respectively.  If you really want to confuse, you could use widdershins as well.

R, 54 bytes
Several bytes saved by @Giuseppe and @J.Doe.
f=function(m)if(ncol(m))c(m[,1],f(t(m[nrow(m):1,-1])))

Try it online!
Recursively strip off the first column and row-reverse/transpose (making the bottom row the new first column) the rest of the matrix until you end up with only one column. Ungolfed "traditional" version:
f <- function(m) {
 if(ncol(m) == 1) {
    m
  } else {
    c(m[,1], f(t(m[nrow(m):1,-1])))
  }
}

It was pointed out that ncol(m) could be golfed to sum(m) to save another byte because we are allowed to assume positive integer matrix values. But I'll leave it like this since it works for all matrices (even matrices of strings!)

wow! I love how the use of t() prevents the drop=TRUE default for \[`` from screwing up the `if` condition!

and full disclosure, I had about a 200 byte solution that didn't even work, so kudos to ya! I'll probably get around to awarding you a bounty for this once the question is eligible for a bounty.

@Giuseppe back to 59 bytes! I was pleasantly surprised by t() to not have to use an is.null test that was in my original attempts.

Isn't that last m going to be null anyway, so you can change the if-statement for 54 bytes. Seems to work for the test cases.

Python 2, 52 bytes
f=lambda a:a and zip(*a)[0]+f(zip(*a[::-1])[1:])or()

Try it online!

Pyth, 9 bytes
shMM.utC_

Try it here!
How?
shMM.utC_     Full program. Takes a 2D array (matrix) from STDIN.
    .u        Until a result that has occurred before is found, loop and collect...
        _     Reverse the matrix (reverse the order of its rows).
       C      Transpose.
      t       Remove first element.
 hMM          For each element in the resulting 3D array, get the heads of its elements.
s             Flatten.

Thats cool. As a Pyth beginner I now know I have a lot to learn,

Stax, 7 bytes
ôQÖG·í<

Run and debug it
It takes an array of rows on one line, and produces newline-separated output.
Unpacked, ungolfed, and commented, it looks like this.
W       repeat the rest of the program until cancelled explicitly
  rM    rotate matrix *clock-wise* (yes, this is the opposite of the challenge)
  |c    assert matrix is truthy. (has rows) cancel otherwise.
  B     remove the top row of the matrix, and push separately to main stack
  rm    reverse the top row (this fixes the rotation direction), and print each value

Run this one

Pyth, 20 bytes
J.TQWJ=+YhJ=J_.TtJ)Y

Try it here
Explanation
J.TQWJ=+YhJ=J_.TtJ)Y
J.TQ                    Call the transposed input J.
    WJ            )     While J is not empty...
      =+YhJ             ... put the top row into Y (initially [])...
           =J   tJ      ... remove the top row...
             _.T        ... reverse and transpose (rotate clockwise).
                   Y    Output the result.

oK, 12 bytes
*+,/(1_+|:)\

Try it online!
This abuses the fact that oK doesn't seem to care too much about shape for transposition. In k this would be 13 bytes: *:',/(1_+|:)\.
       +|:   /reverse, then transpose (rotate right)
     1_      /remove first line
    (     )\ /fixpoint of the above, keeping intermediate results (scan)
  ,/         /concatenate all the rows
*+           /get the first element of each row

Clean, 69 bytes
import StdEnv,StdLib
? =transpose
@[h:t]=h++ @(reverse(?t))
@_=[]

@o?

Try it online!
Moves the next row/column to the head of the list so it can pattern matched in the argument.
For the first example in the challenge, this looks like:
@o? [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
@ h=:[1, 5, 9, 13] t=:[[2, 6, 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]]
[1, 5, 9, 13] ++ @ h=:[14, 15, 16] t=:[[10, 11, 12], [6, 7, 8], [2, 3, 4]]
[1, 6, 9, 13, 14, 15, 16] ++ @ h=:[12, 8, 4] t=:[[11, 7, 3], [10, 6, 2]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4] ++ @ h=:[3, 2] t=:[[7, 6], [11, 10]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2] ++ @ h=:[6, 10] t=:[[7, 11]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10] ++ @ h=:[11, 7] t=:[]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10, 11, 7] ++ @ []

Julia 0.7, 47 bytes
f(m)=[m[:,1];sum(m)<1?[]:f(rotr90(m[:,2:end]))]

Try it online!
Julia has a convenient built-in to rotate the matrix by 90 degrees eliminating the need for transpose-reverse operations.
As you can see from the compiler warnings, it insists that all components of the ternary conditional should be separated by spaces, and in v. 1.0 this has been actually enforced.
Oddly enough, in this situation the shortest way I found to break out of recursion was to use a try-catch block:
Julia 1.0, 50 bytes
f(m)=[m[:,1];try f(rotr90(m[:,2:end]))catch;[]end]

Try it online!

JavaScript (Node.js), 89 bytes
f=a=>a>[]?[...a.map(x=>x[0]),...f(a[0].map((_,i)=>a.map(y=>y[i]).reverse()).slice(1))]:[]

Try it online!
Takes the first column, transpose the remaining one then reverse each row (= rotate the matrix 90 degrees CW), and then repeat until the array has no more entries.

05AB1E, 13 11 10 bytes
ΔRøćRˆ}¯˜þ

-2 bytes thanks to @Emigna.
Try it online or verify all test cases.
Explanation:
Δ         # Loop until the stack no longer changes:
 R        #  Reverse the order of the rows
          #   i.e. [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
          #    → [[13,14,15,16],[9,10,11,12],[5,6,7,8],[1,2,3,4]]
  ø       #  Zip, swapping rows and column
          #   → [[13,9,5,1],[14,10,6,2],[15,11,7,3],[16,12,8,4]]
   ć      #  Head extracted
          #   → [[14,10,6,2],[15,11,7,3],[16,12,8,4]] and [13,9,5,1]
    R     #  Reverse this row
          #   → [1,5,9,13]
     ˆ    #  Pop and push it to the global array
}         # After the loop:
 ¯        #  Push the global array
          #   i.e. [[1,5,9,13],[14,15,16],[12,8,4],[3,2],[6,10],[11],[7],"",""]
  ˜       #  Flatten it
          #   → [1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7,"",""]
   þ      #  Remove all empty string by only leaving all digits
          #   → ["1","5","9","13","14","15","16","12","8","4","3","2","6","10","11","7"]
          # (and output it implicitly)

APL (Dyalog), 24 22 bytes
{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}

Try it online!
How?
{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}
{                    } - a function
 ×≢⍵:                  - if non-empty:
     ⍵[;1]             - the left column
          ,∇⍉⊖0 1↓⍵    - repeat this function without the left column, rotated counter clockwise
                   ⋄⍬  - otherwise, return an empty vector

An explanation of the operators would be nice.

@Arc676, added!

Jelly, 9 bytes
ZḊUƊƬḢ€€Ẏ

Try it online!

Charcoal, 25 bytes
≔⮌ＥＡ⮌ιθＷθ«≔Ｅ§θ⁰⮌Ｅθ§μλθＩ⊟θ

Try it online! Link is to verbose version of code. Explanation:
≔⮌ＥＡ⮌ιθ

Rotate the input by 180°. This is for two reasons: a) the last row is the easiest to remove, and b) it's easier to loop if the row is removed at the end of the loop. (I did try reflecting and outputting clockwise but that took an extra byte.)
Ｗθ«

Repeat until the array is empty.
≔Ｅ§θ⁰⮌Ｅθ§μλθ

Rotate the array by 90°.
Ｉ⊟θ

Remove the last row of the array and print the element as strings on separate lines.

Ruby, 65 bytes
->a{x,*a=a.transpose;(w,*a=a.transpose.reverse;x+=w)while a[0];x}

Try it online!

PowerShell, 266 bytes
Yeah..  PowerShell isn't the best for handling matrices.  But, the algorithm is basically the same as the above..  Each row is represented as a comma-separated string, and we basically do a rotation and transposition for each layer.  I can probably shave more off, but... I am already in my pajamas...
Filter F{$a=$_-replace"],|]|\s",''-split'\['|?{$_-ne''};$b=@();while($a-ne $null){$N=($a[0]-split',').Count-1;$a=0..$N|%{$i=$_;($a|%{($_-split',')[$i]})-join','};if($d){[array]::Reverse($a)}if($N-gt0){$b+=$a[0];$a=$a[1..$N]}else{$b+=$a;$a=$null};$d=$true}$b-join','}

Try it online!


text:
Pentomino 6x10 solution normalizer
As you most probably now, there are 2339 solutions to pentomino puzzle in a 6x10 grid. There are different labeling schemes for the 12 pentominoes, two of them are shown on the image below:

Image credit: Wikipedia
For the purposes of the current task we will say that a normalized pentomino solution is a solution that uses the second labeling scheme (Conway’s).
Example:
O O O O O S S S Z Z
P P R R S S W W Z V
P P P R R W W Z Z V
U U X R T W Y V V V
U X X X T Y Y Y Y Q
U U X T T T Q Q Q Q

The piece with 5 squares in a row is denoted with letters O, according to the scheme. The same is true for all pieces.
Task:
Given a solution to the 6x10 pentomino in which the pieces are labeled with a random sheme, normalize it so that all pieces are labeled in Conway’s labeling scheme. You need to recognize the pieces and mark each square of a particular piece with the symbol of the piece.
Input:
The solution to be normalized, in any format that is convenient for you, for example:

A multiline string
A list of strings
A list of lists of characters

and so on
Output:
The same solution (all the pieces positions and orientation preserved), but each piece labeled according to Conway’s labeling scheme.
Note: The output MUST be PRINTED as a 6x10 grid of characters. Leading and trailing newlines and spaces are permitted. You can also print a space between the characters (but not empty lines), as in the example above.
Test cases:
1.
Input:
6623338888
6222344478
66A234BB70
1AAA94B770
11A99BB700
1199555550

Output:
UURTTTQQQQ
URRRTVVVSQ
UUXRTVZZSY
PXXXWVZSSY
PPXWWZZSYY
PPWWOOOOOY

2.
Input:
45ookkkk00
455ooogk00
4a55gggdd0
4aaa3gnnd.
4am333ndd.
mmmm3nn...

Output:
OWSSQQQQPP
OWWSSSRQPP
OTWWRRRUUP
OTTTXRZZUV
OTYXXXZUUV
YYYYXZZVVV

Winning criteria:
The shortest solution in bytes in each language wins. Don’t be discouraged by the golfing languages. Explanations of the algorithms and implementations are welcome.

Related: Which tetromino is this? and related: Print a Pentomino Rectangle.

@KevinCruijssen Thank you! (I didn't check for questions related to tetromonoes)

APL (Dyalog Classic), 54 53 50 bytes
⍴⍴{'OXRYTPZQUWSV'[⌊5÷⍨⍋⍋,{×/+⌿↑|(⊢-+/÷≢)⍸⍵}¨⍵=⊂⍵]}

Try it online!
Compute an invariant for each pentomino in the input: measure (∆x,∆y) from each of its squares to its centre of gravity, take abs(∆x) and abs(∆y), sum the x components and separately the y components, and multiply the two sums. This gives 12 distinct results. Then, find the index of each pentomino's invariant in the sorted collection of all invariants. Replace 0 with 'O', 1 with 'X', 2 with 'R', etc.

Thank you for the fast answer and the explanation, +1 from me!
I meant the solution to be explicitly printed as a 6x10 grid. I changed the descrition, please update your solution - I'm sorry for the inconvenience.

@GalenIvanov but... it is a grid. My tests output "ok" instead of printing the result - maybe that's too confusing?

Yes, I was confused by the tests.

now they print the result before validating it

Jelly, 37 bytes
ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY

A full program taking a list of strings (because we must print - otherwise remove the trailing Y and you have a monad taking a list of lists of numbers or characters which returns a list of lists of characters).
Try it online!
How?
I believe this works using the same categorisation of pentominos as ngn's APL solution, albeit in a slightly different way (I also don't know APL so I'm not that sure how similar the method is beyond the categorisation).
(Note that “æṂ⁾+’Œ?¤+78Ọ is only a one-byte save over “XRPTZWUYSVQO”!)
ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY - Main Link: list of lists of characters L
ŒĠ                                    - group multidimensional indices by value
      Ɗ€                              - last three links as a monad for €ach i.e. f(x):
  Z                                   -   transpose x
   Æm                                 -   mean (vectorises) (i.e. the average of the coordinates)
     ạ                                -   absolute difference with x (vectorises) (i.e. [dx, dy])
         ı                            - square root of -1 (i)
        ḅ                             - convert from base (vectorises) (i.e a list of (i*dx+dy)s)
          §                           - sum each
           A                          - absolute value (i.e. norm of the complex number)
            Ụ                         - grade up (sort indices by value)
             Ụ                        - grade up (...getting the order from the result of A back,
                                      -              but now with one through to 12)
                       ¤              - nilad followed by links as a nilad:
               “æṂ⁾+’                 -   base 250 literal = 370660794
                     Œ?               -   permutation@lex-index = [10,4,2,6,12,9,7,11,5,8,3,1]
              ị                       - index into
                        +78           - add seventy-eight
                           Ọ          - cast to characters (character(1+78)='O', etc...)
                                 Ɗ    - last three links as a monad (i.e. f(L)):
                              F       -   flatten
                               Q      -   de-duplicate
                                Ṣ     -    sort
                            ,@        - pair (with sw@pped @rguments) (giving a list of 2 lists)
                                   Ɱ  - Ɱap across L with:
                                  y   -   translate i.e. swap the letters as per the the pair)
                                    Y - join with new lines
                                      - implicit print

Wolfram Language (Mathematica), 103 bytes
""<>Riffle[(t=#)/.Thread[SortBy[Union@@t,Tr@Kurtosis@Position[t,#]&]->Characters@"UPSWZVRTQXYO"],"\n"]&

Takes input as a list of lists of characters.
Try it online!
The main idea here is that for each character in the input, we find the coordinates where it occurs, take the kurtosis and sum its coordinates. This gives us an invariant for each piece.
(The kurtosis is some mostly-irrelevant operator from statistics - the key is that it's invariant under translation, while reflection and rotation might switch the order of coordinates at most. We sum the coordinates, so the invariant never changes.)
Anyway, apart from the weird invariant, this solution is similar to the others: we sort the characters and the pieces by each invariant, then replace each character by the corresponding character of "UPSWZVRTQXYO": the pieces, sorted by kurtosis sum.
Finally, ""<>Riffle[...,"\n"] is the print-as-a-grid code.

+1 for knowing an operation that I never even heard of and putting it to good use

My first attempt at a solution had Sort@Variance in place of Tr@Kurtosis, and probably more people have heard of variance. But Tr@Variance doesn't work because several pentominoes (such as P and X) have the same sum of x-variance and y-variance. So I went looking through Mathematica's documentation for something fancier.

Python 2, 191 bytes
def y(o):print"".join(['XPRTWZUYSVQO\n'[[w for v,w in sorted([sum(abs(u-sum(t)/5)for t in[[complex(r%11,r/11)for r,q in enumerate(o)if q==p]]for u in t),p]for p in o)].index(x)/5]for x in o])

Try it online!
Takes a multi-line string with a trailing newline and does six nested list comprehensions.
Ungolfed Version
def pentomino_normalizer(input_string):
    # input_string is a multi-line string with a trailing newline

    results = []  # For saving the results of the for loop
    for current_char in input_string:
        # current_char = p in the golfed version

        # The python data type complex stores a real and a imaginary value and
        # is used for storing the x and y coordinates.
        # In the end, the positions list contains a complex number for every
        # occurence of current_char in the string
        # positions_list = t in the golfed version
        positions_list = [complex(i % 11, i / 11) for i, c
                          in enumerate(input_string) if c == current_char]
        # average_pos is the midpoint of all occurences of current_char,
        # to get rid of translations
        average_pos = sum(positions_list)/5
        # Calculates a value for each tile that is invariant under
        # translations and rotations,
        # simply the sum of all the distances between the midpoint
        # and the positions
        invariant = sum(abs(pos - average_pos) for pos in positions_list)

        # Saves the invariant value to a list
        results.append(invariant, current_char)

    # This new list contains the characters occuring in the string, sorted
    # by the invariant value. Because this was done with each char in the
    # input string, this lists contains every value five times and also
    # contains six newlines
    # at the end of the list
    sorted_results = [w for v, w in sorted(results)]

    # This code snippet maps each char from the input string to its according
    # output and prints to stdout
    chars = ['XPRTWZUYSVQO\n'[sorted_results.index(c)/5] for c in input_string]
    print "".join(chars)