functions as valuesiterating listsnegative remainderP0239
Shaping a list by passing rule functions
A list of integers is shaped by s rules, one after another.
The first line gives n, and the second line gives n integers separated by spaces.
The third line gives s, and each of the next s lines gives one rule in the form "name k".
There are six rules. The first three change every number in the list, and the last three keep only the numbers that meet a condition.
add k: change every number x to x + k.
mul k: change every number x to x × k.
mod k: change every number x to the remainder r of x divided by k. Here r is at least 0 and less than k, and x - r is a multiple of k. So the remainder of -7 divided by 3 is 2.
gt k: keep only the numbers greater than k.
lt k: keep only the numbers less than k.
div k: keep only the multiples of k. 0 and negative numbers can be multiples of k too.
The numbers that remain keep their order.
Each time you apply a rule, print the list after that rule on one line, separated by single spaces.
If the list is empty, print -. Applying the next rule to an empty list gives an empty list.
In your solution, write two functions that take "a list, a rule function, k" and return a new list. One changes every number, and the other keeps only the numbers that meet the condition.
For each rule, call one of these two functions, passing that rule's function as a value.
Input
1 ≤ n ≤ 300, 1 ≤ s ≤ 20, the starting numbers are from -1,000,000 to 1,000,000. For add -1,000,000 ≤ k ≤ 1,000,000, for mul -10 ≤ k ≤ 10, for mod 1 ≤ k ≤ 1,000, for gt and lt -1,000,000,000 ≤ k ≤ 1,000,000,000, for div 1 ≤ k ≤ 100. At every step, every number in the list has an absolute value of at most 1,000,000,000
Output
One line per rule: the list at that point, or - if it is empty
Example 1 · stdin
5
3 -7 10 0 5
4
mul 2
mod 4
gt 0
add -1
stdout
6 -14 20 0 10
2 2 0 0 2
2 2 2
1 1 1
Example 2 · stdin
4
2 4 6 1
2
div 2
lt 0
stdout
2 4 6
-
main.py
Error List00F8 ↓ · ⇧F8 ↑
Input (stdin)
When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).
$ Ready
Open this on a computer to write and run code. On mobile you can read the problem and the solutions.
In other languagesShow solutions by language · 8 languages
Each language passes functions as values in its own way. Python passes a function name made with def, or lambda x, k: x + k, as is, and JS/TS pass an arrow function (x, k) => x + k (TS adds a function type such as (x: number, k: number) => number). Java needs a functional interface to receive a lambda, so it uses IntBinaryOperator and BiPredicate<Integer, Integer>, and C# uses Func<int, int, int> and Func<int, int, bool>. C passes a function pointer int (*rule)(int, int), and C++ stores a lambda in std::function<int(int, int)>. Craykon has no lambdas, so you make named functions such as add(x, k), pass them by name, and pick them from a Dict() of name → function. The first trap is the remainder of a negative number. In JS/TS, Java, C#, C, C++ and Craykon, % follows the sign of the dividend, so -7 % 3 is -1. Only Python's % gives 2. Fix it with (x % k + k) % k, or use Java Math.floorMod(x, k). The second trap is how you filter. In Python, calling a.remove(x) inside for x in a: pulls the later items forward and skips the very next number, so put the numbers to keep in a new list. JS/TS map / filter and the two functions in this problem return a new list, so nothing changes unless you store the returned list. gt and lt do not keep a number equal to k, so they are > and <, not >= and <=.
Pythonmain.py · 41 lines
# 모든 수를 바꾸는 규칙(x, k → 새 수)def add(x, k): return x + kdef mul(x, k): return x * kdef mod(x, k): return x % k # Python의 %는 k가 양수면 늘 0 이상 k 미만# 남길지 정하는 규칙(x, k → 참·거짓)def gt(x, k): return x > kdef lt(x, k): return x < kdef div(x, k): return x % k == 0# 함수를 값으로 받는 함수 두 개def change_all(a, rule, k): return [rule(x, k) for x in a]def keep_only(a, rule, k): return [x for x in a if rule(x, k)]CHANGE = {"add": add, "mul": mul, "mod": mod}KEEP = {"gt": gt, "lt": lt, "div": div}n = int(input())a = list(map(int, input().split()))s = int(input())for _ in range(s): name, k = input().split() k = int(k) if name in CHANGE: a = change_all(a, CHANGE[name], k) else: a = keep_only(a, KEEP[name], k) print(" ".join(map(str, a)) if a else "-")
JavaScriptmain.js · 28 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");// 모든 수를 바꾸는 규칙(x, k → 새 수). JS의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다const CHANGE = { add: (x, k) => x + k, mul: (x, k) => x * k, mod: (x, k) => ((x % k) + k) % k,};// 남길지 정하는 규칙(x, k → 참·거짓)const KEEP = { gt: (x, k) => x > k, lt: (x, k) => x < k, div: (x, k) => x % k === 0,};// 함수를 값으로 받는 함수 두 개. map·filter는 새 배열을 돌려준다const changeAll = (a, rule, k) => a.map((x) => rule(x, k));const keepOnly = (a, rule, k) => a.filter((x) => rule(x, k));let a = lines[1].trim().split(/\s+/).map(Number);const s = Number(lines[2]);const out = [];for (let i = 0; i < s; i++) { const [name, ks] = lines[3 + i].trim().split(/\s+/); const k = Number(ks); a = name in CHANGE ? changeAll(a, CHANGE[name], k) : keepOnly(a, KEEP[name], k); // -0 % 3은 -0이지만 join은 "0"으로 쓴다 out.push(a.length ? a.join(" ") : "-");}console.log(out.join("\n"));
TypeScriptmain.ts · 30 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");type Change = (x: number, k: number) => number;type Keep = (x: number, k: number) => boolean;// 모든 수를 바꾸는 규칙. JS·TS의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다const CHANGE: Record<string, Change> = { add: (x, k) => x + k, mul: (x, k) => x * k, mod: (x, k) => ((x % k) + k) % k,};// 남길지 정하는 규칙const KEEP: Record<string, Keep> = { gt: (x, k) => x > k, lt: (x, k) => x < k, div: (x, k) => x % k === 0,};// 함수를 값으로 받는 함수 두 개const changeAll = (a: number[], rule: Change, k: number): number[] => a.map((x) => rule(x, k));const keepOnly = (a: number[], rule: Keep, k: number): number[] => a.filter((x) => rule(x, k));let a: number[] = lines[1].trim().split(/\s+/).map(Number);const s: number = Number(lines[2]);const out: string[] = [];for (let i = 0; i < s; i++) { const [name, ks] = lines[3 + i].trim().split(/\s+/); const k: number = Number(ks); a = name in CHANGE ? changeAll(a, CHANGE[name], k) : keepOnly(a, KEEP[name], k); out.push(a.length ? a.join(" ") : "-");}console.log(out.join("\n"));
JavaMain.java · 56 lines
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.StringTokenizer;import java.util.function.BiPredicate;import java.util.function.IntBinaryOperator;public class Main { // 함수를 값으로 받는 함수 두 개 static List<Integer> changeAll(List<Integer> a, IntBinaryOperator rule, int k) { List<Integer> b = new ArrayList<>(); for (int x : a) b.add(rule.applyAsInt(x, k)); return b; } static List<Integer> keepOnly(List<Integer> a, BiPredicate<Integer, Integer> rule, int k) { List<Integer> b = new ArrayList<>(); for (int x : a) if (rule.test(x, k)) b.add(x); return b; } public static void main(String[] args) throws Exception { Map<String, IntBinaryOperator> change = new HashMap<>(); change.put("add", (x, k) -> x + k); change.put("mul", (x, k) -> x * k); change.put("mod", Math::floorMod); // %는 음수에서 음수가 나온다. floorMod는 0 이상 k 미만 Map<String, BiPredicate<Integer, Integer>> keep = new HashMap<>(); keep.put("gt", (x, k) -> x > k); keep.put("lt", (x, k) -> x < k); keep.put("div", (x, k) -> x % k == 0); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); List<Integer> a = new ArrayList<>(); StringTokenizer st = new StringTokenizer(in.readLine()); while (st.hasMoreTokens()) a.add(Integer.parseInt(st.nextToken())); int s = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int i = 0; i < s; i++) { st = new StringTokenizer(in.readLine()); String name = st.nextToken(); int k = Integer.parseInt(st.nextToken()); a = change.containsKey(name) ? changeAll(a, change.get(name), k) : keepOnly(a, keep.get(name), k); if (a.isEmpty()) { out.append("-\n"); continue; } for (int j = 0; j < a.size(); j++) out.append(j > 0 ? " " : "").append(a.get(j)); out.append('\n'); } System.out.print(out); }}
C#Main.cs · 50 lines
using System;using System.Collections.Generic;using System.Text;class Program{ // 함수를 값으로 받는 함수 두 개 static List<int> ChangeAll(List<int> a, Func<int, int, int> rule, int k) { var b = new List<int>(); foreach (int x in a) b.Add(rule(x, k)); return b; } static List<int> KeepOnly(List<int> a, Func<int, int, bool> rule, int k) { var b = new List<int>(); foreach (int x in a) if (rule(x, k)) b.Add(x); return b; } static void Main() { var change = new Dictionary<string, Func<int, int, int>> { ["add"] = (x, k) => x + k, ["mul"] = (x, k) => x * k, ["mod"] = (x, k) => ((x % k) + k) % k, // %는 음수에서 음수가 나온다 }; var keep = new Dictionary<string, Func<int, int, bool>> { ["gt"] = (x, k) => x > k, ["lt"] = (x, k) => x < k, ["div"] = (x, k) => x % k == 0, }; Console.ReadLine(); var a = new List<int>(); foreach (string t in Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries)) a.Add(int.Parse(t)); int s = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); for (int i = 0; i < s; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int k = int.Parse(p[1]); a = change.TryGetValue(p[0], out var f) ? ChangeAll(a, f, k) : KeepOnly(a, keep[p[0]], k); sb.Append(a.Count > 0 ? string.Join(" ", a) : "-").Append('\n'); } Console.Write(sb); }}
C++main.cpp · 48 lines
#include <functional>#include <iostream>#include <map>#include <string>#include <vector>using Change = std::function<int(int, int)>;using Keep = std::function<bool(int, int)>;// 함수를 값으로 받는 함수 두 개std::vector<int> changeAll(const std::vector<int> &a, const Change &rule, int k) { std::vector<int> b; for (int x : a) b.push_back(rule(x, k)); return b;}std::vector<int> keepOnly(const std::vector<int> &a, const Keep &rule, int k) { std::vector<int> b; for (int x : a) if (rule(x, k)) b.push_back(x); return b;}int main() { const std::map<std::string, Change> change = { {"add", [](int x, int k) { return x + k; }}, {"mul", [](int x, int k) { return x * k; }}, {"mod", [](int x, int k) { return (x % k + k) % k; }}, // %는 음수에서 음수가 나온다 }; const std::map<std::string, Keep> keep = { {"gt", [](int x, int k) { return x > k; }}, {"lt", [](int x, int k) { return x < k; }}, {"div", [](int x, int k) { return x % k == 0; }}, }; int n, s, k; std::cin >> n; std::vector<int> a(n); for (int &x : a) std::cin >> x; std::cin >> s; std::string name; for (int i = 0; i < s; i++) { std::cin >> name >> k; auto it = change.find(name); a = it != change.end() ? changeAll(a, it->second, k) : keepOnly(a, keep.at(name), k); if (a.empty()) std::cout << '-'; for (std::size_t j = 0; j < a.size(); j++) std::cout << (j ? " " : "") << a[j]; std::cout << '\n'; }}
Cmain.c · 46 lines
#include <stdio.h>#include <string.h>/* 모든 수를 바꾸는 규칙과 남길지 정하는 규칙. 함수 포인터로 넘긴다 */int add(int x, int k) { return x + k; }int mul(int x, int k) { return x * k; }int mod(int x, int k) { return (x % k + k) % k; } /* C의 %는 음수에서 음수가 나온다 */int gt(int x, int k) { return x > k; }int lt(int x, int k) { return x < k; }int divisible(int x, int k) { return x % k == 0; }/* 함수를 값으로 받는 함수 두 개. 남긴 개수를 돌려준다 */int change_all(int *a, int n, int (*rule)(int, int), int k) { for (int i = 0; i < n; i++) a[i] = rule(a[i], k); return n;}int keep_only(int *a, int n, int (*rule)(int, int), int k) { int m = 0; for (int i = 0; i < n; i++) { if (rule(a[i], k)) a[m++] = a[i]; /* 앞으로 당겨 담는다 */ } return m;}int main(void) { struct { const char *name; int (*fn)(int, int); int changes; } rules[] = { {"add", add, 1}, {"mul", mul, 1}, {"mod", mod, 1}, {"gt", gt, 0}, {"lt", lt, 0}, {"div", divisible, 0}, }; int n, s, k, a[300]; char name[8]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &s); for (int step = 0; step < s; step++) { scanf("%7s %d", name, &k); for (int r = 0; r < 6; r++) { if (strcmp(rules[r].name, name) != 0) continue; n = rules[r].changes ? change_all(a, n, rules[r].fn, k) : keep_only(a, n, rules[r].fn, k); } if (n == 0) puts("-"); for (int i = 0; i < n; i++) printf(i + 1 < n ? "%d " : "%d\n", a[i]); } return 0;}
Craykonmain.cray · 90 lines
// 모든 수를 바꾸는 규칙(x, k → 새 수)더하기(x, k){ return x + k;}곱하기(x, k){ return x * k;}나머지(x, k){ // 크레이콘의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다 return (x % k + k) % k;}// 남길지 정하는 규칙(x, k → 참·거짓)큰것만(x, k){ return x > k;}작은것만(x, k){ return x < k;}배수만(x, k){ return x % k == 0;}// 함수를 값으로 받는 함수 두 개. 크레이콘에는 람다가 없으니 이름으로 넘긴다모두바꾸기(a, 규칙, k){ b = []; foreach (x in a) { b.Add(규칙(x, k)); } return b;}골라남기기(a, 규칙, k){ b = []; foreach (x in a) { if (규칙(x, k)) { b.Add(x); } } return b;}change = Dict();change["add"] = 더하기;change["mul"] = 곱하기;change["mod"] = 나머지;keep = Dict();keep["gt"] = 큰것만;keep["lt"] = 작은것만;keep["div"] = 배수만;Console.ReadLine();a = Console.ReadNumbers();s = Console.ReadLine().ToNumber();for (i = 0; i < s; i++){ p = Console.ReadLine().Split(); k = p[1].ToNumber(); if (change.Contains(p[0])) { a = 모두바꾸기(a, change[p[0]], k); } else { a = 골라남기기(a, keep[p[0]], k); } if (a.Count == 0) { Console.WriteLine("-"); } else { Console.WriteLine(a.Join(" ")); }}