Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

printf 2 #14427

Open
ethereal-sheep opened this issue Aug 12, 2022 · 2 comments · May be fixed by #14428
Open

printf 2 #14427

ethereal-sheep opened this issue Aug 12, 2022 · 2 comments · May be fixed by #14428
Labels
new-challenge Propose a new challenge, a PR will be auto generated

Comments

@ethereal-sheep
Copy link

ethereal-sheep commented Aug 12, 2022

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty:  hard
title: printf 2
tags: template-literal

Question

printf is a c function which prints a format string with some arguments to stdout.

For this challenge, your task is to implement the Printf type which takes a format string as the first generic argument, and an array of arguments as the second generic argument.

Printf must follow a couple of rules.

  1. %d | %s | %b wildcards must be replaced with the appropriate type arguments.
    1.1 %d replaced with number
    1.2 %s replaced with string
    1.3 %b replaced with boolean
  2. %% must be escaped to a single %.
  3. Number of wildcards and arguments must be the same; else never.

Example:

type str = Printf<'%s %s', ['Hello', 'World']> // str: 'Hello World'

Template

type Printf<Fs extends string, Args extends any[]> = any

Test Cases

import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<Printf<'%s %s', ['Hello', 'World']>, 'Hello World'>>,
  Expect<Equal<Printf<'%s %d %s %b', ['All', 3, 'types', true]>, 'All 3 types true'>>,
  Expect<Equal<Printf<'Invalid', [true]>, never>>,
  Expect<Equal<Printf<'Invalid %b', []>, never>>,
  Expect<Equal<Printf<'Bad Order %d %s %b', [true, 1, 's']>, never>>,
  Expect<Equal<Printf<'Valid %%%b', [true]>, 'Valid %true'>>,
  Expect<Equal<Printf<'Convoluted %d%d%%%d%%%d %d', [1,2,3,4,5]>, 'Convoluted 12%3%4 5'>>,
  Expect<Equal<Printf<'Seems Wrong %%s %%d %%b', []>, 'Seems Wrong %s %d %b'>>,
  Expect<Equal<Printf<'Nothing happens %s %s %s', ['%s', '%s', '%s']>, 'Nothing happens %s %s %s'>>,
]

Solution:

type Printf<Fs extends string, Ts extends any[]> = 
  Fs extends `${infer Fl}%${infer C extends 's' | 'd' | 'b'}${infer Fr}` ?
    C extends 's' ?
      Ts extends [infer Tl extends string, ...infer Tr extends any[]] ?
        `${Fl}${Tl}${Printf<Fr, Tr>}` : never :
    C extends 'd' ?
      Ts extends [infer Tl extends number, ...infer Tr extends any[]] ?
        `${Fl}${Tl}${Printf<Fr, Tr>}` : never :
    C extends 'b' ?
      Ts extends [infer Tl extends boolean, ...infer Tr extends any[]] ?
        `${Fl}${Tl}${Printf<Fr, Tr>}` : never : 
    never :
  Fs extends `${infer Fl}%%${infer Fr}` ?      
     `${Fl}%${Printf<Fr, Ts>}` : 
  Fs extends `${infer Fl}${infer Fr}` ?      
     `${Fl}${Printf<Fr, Ts>}` : 
  Ts extends [any] ? never :
  Fs
@ethereal-sheep ethereal-sheep added the new-challenge Propose a new challenge, a PR will be auto generated label Aug 12, 2022
@github-actions github-actions bot linked a pull request Aug 12, 2022 that will close this issue
@github-actions
Copy link
Contributor

github-actions bot commented Aug 12, 2022

#14428 - Pull Request updated.

2022-09-01T09:57:35.710Z Preview in Playground

github-actions bot pushed a commit that referenced this issue Aug 12, 2022
github-actions bot pushed a commit that referenced this issue Sep 1, 2022
@ethereal-sheep
Copy link
Author

Updated testcases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-challenge Propose a new challenge, a PR will be auto generated
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant