읔
제가 아는 내에서의 결론은 기본 LINQ 만으로 Console 케이스를 만족하는 코드는 불가능하다 입니다 ㅋㅋㅋ
Console 아닌 케이스에서 잘 동작하는 LINQ 코드
static IEnumerable<int> Extract(IEnumerable<int> numbers) => numbers
.Zip(numbers.Cast<int?>().Prepend(null)
.Zip(new int?[2].Concat(numbers.Cast<int?>()), (prev, prePrev) => (prev, prePrev)))
.Where(x => x.Second.prePrev + 1 != x.Second.prev && x.Second.prev + 1 == x.First)
.Select(x => x.Second.prev.Value);
아마도 입력으로 들어오는 IEnumerable<int> numbers
를 두 군데 이상에서 사용하고 있기 때문일 것 같은데요.
@루나시아 님 답변을 참고한 Aggregate()
사용
public static IEnumerable<int> Extract(IEnumerable<int> numbers) => numbers
.Aggregate<int, (int? prePrev, int? prev, IEnumerable<int> result)>((null, null, []), (x, current) =>
(x.prev, current, x.prePrev + 1 != x.prev && x.prev + 1 == current ? x.result.Append(x.prev.Value) : x.result)).result;
이것 역시 Aggregate()
메서드의 실행 결과 값인 result
필드를 반환하여 사용하므로 Console서 동작 불가
아마 Aggregate()
와 Select()
의 속성을 합친 메서드가 제공된다 가능할 것입니다.
단일 입력 참조를 위한 AggregateSelect()
메서드 사용
Aggregate.cs (dot.net)
Aggregate()
메서드의 구현을 살짝 바꿔 마지막 결과를 반환하지 않고 중간 과정을 yield return
해주는 AggregateSelect()
메서드를 만듭니다.
public static IEnumerable<TAccumulate> AggregateSelect<TSource, TAccumulate>(
this IEnumerable<TSource> source,
TAccumulate seed, Func<TAccumulate,
TSource, TAccumulate> func)
{
TAccumulate result = seed;
foreach (TSource element in source)
{
var current = func(result, element);
yield return current;
result = current;
}
}
이놈을 이용하면
static IEnumerable<int> Extract(IEnumerable<int> numbers) => numbers
.AggregateSelect(
(prePrev: default(int?), prev: default(int?), current: default(int?)),
(x, current) => (x.prev, x.current, current))
.Where(x => x.prePrev + 1 != x.prev && x.prev + 1 == x.current)
.Select(x => x.prev.Value);
Console 입력에도 동작하는 깔끔~한 코드가 나오지만 요렇게 하면 반칙!! 